diff --git a/.github/changelog.json b/.github/changelog.json new file mode 100644 index 000000000..4fe255e69 --- /dev/null +++ b/.github/changelog.json @@ -0,0 +1,16 @@ +{ + "categories": [ + { + "title": "## Features", + "labels": ["T-feature"] + }, + { + "title": "## Fixes", + "labels": ["T-bug", "T-fix"] + } + ], + "ignore_labels": ["L-ignore"], + "template": "${{CHANGELOG}}\n## Other\n\n${{UNCATEGORIZED}}", + "pr_template": "- ${{TITLE}} (#${{NUMBER}})", + "empty_template": "- No changes" +} diff --git a/.github/workflows/contracts-tests.yml b/.github/workflows/contracts-tests.yml new file mode 100644 index 000000000..96fcd515a --- /dev/null +++ b/.github/workflows/contracts-tests.yml @@ -0,0 +1,128 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + branches: + - "**" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + solidity-unit-tests: + name: solidity-unit-tests + runs-on: ubuntu-22.04 + timeout-minutes: 10 + steps: + - name: Checkout repository and submodules + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run unit tests + run: | + export PATH=$PATH:$HOME/.foundry/bin + forge test -vvv + + teleporter_e2e: + name: teleporter-e2e-tests + runs-on: ubuntu-22.04 + steps: + - name: Checkout repositories and submodules + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: "go.mod" + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run E2E Tests + # Forge installs to BASE_DIR, but updates the PATH definition in $HOME/.bashrc + run: | + export PATH=$PATH:$HOME/.foundry/bin + export PATH="$PATH:$GOPATH/bin" + ./scripts/contracts_e2e_test.sh --components teleporter + + governance_e2e: + name: governance-e2e-tests + runs-on: ubuntu-22.04 + steps: + - name: Checkout repositories and submodules + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run E2E Tests + # Forge installs to BASE_DIR, but updates the PATH definition in $HOME/.bashrc + run: | + export PATH=$PATH:$HOME/.foundry/bin + export PATH="$PATH:$GOPATH/bin" + ./scripts/contracts_e2e_test.sh --components governance + + validator_manager_e2e: + name: validator-manager-e2e-tests + runs-on: ubuntu-22.04 + steps: + - name: Checkout repositories and submodules + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run E2E Tests + # Forge installs to BASE_DIR, but updates the PATH definition in $HOME/.bashrc + run: | + export PATH=$PATH:$HOME/.foundry/bin + export PATH="$PATH:$GOPATH/bin" + ./scripts/contracts_e2e_test.sh --components validator-manager + + ictt_e2e: + name: ictt-e2e-tests + runs-on: ubuntu-22.04 + steps: + - name: Checkout repositories and submodules + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run E2E Tests + # Forge installs to BASE_DIR, but updates the PATH definition in $HOME/.bashrc + run: | + export PATH=$PATH:$HOME/.foundry/bin + export PATH="$PATH:$GOPATH/bin" + ./scripts/contracts_e2e_test.sh --components ictt diff --git a/.github/workflows/e2e_granite.yml b/.github/workflows/e2e_granite.yml index e9464f111..caba8e2a4 100644 --- a/.github/workflows/e2e_granite.yml +++ b/.github/workflows/e2e_granite.yml @@ -50,4 +50,4 @@ jobs: submodules: recursive - name: Run E2E Tests - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh --activate-granite + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/relayer_e2e_test.sh --activate-granite diff --git a/.github/workflows/test.yml b/.github/workflows/go-unit-tests.yml similarity index 78% rename from .github/workflows/test.yml rename to .github/workflows/go-unit-tests.yml index c3446aa88..ac4f0eb9f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/go-unit-tests.yml @@ -12,12 +12,12 @@ on: - "**" jobs: - test_relayer: + test_unit: name: Unit tests runs-on: ubuntu-22.04 steps: - - name: Checkout icm-relayer repository + - name: Checkout repository uses: actions/checkout@v5 with: submodules: recursive @@ -27,5 +27,5 @@ jobs: with: go-version-file: 'go.mod' - - name: Run Relayer Unit Tests - run: ./scripts/test.sh + - name: Run Golang Unit Tests + run: ./scripts/unit-test.sh diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 823d4d172..25650bc5b 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,7 +1,7 @@ # Copyright (C) 2023, Ava Labs, Inc. All rights reserved. # See the file LICENSE for licensing terms. -name: Run Golang Linter +name: Run Lint and Format Checks on: push: @@ -12,7 +12,25 @@ on: - "**" jobs: + solhint: + name: solhint + runs-on: ubuntu-22.04 + timeout-minutes: 10 + + steps: + - name: Checkout repository + uses: actions/checkout@v5 # Purposefully not recursive + + - name: Install solhint + run: | + npm install solhint -g + solhint --version + + - name: Run solhint + run: ./scripts/lint.sh --sol-lint + golangci: + name: golanci runs-on: ubuntu-22.04 timeout-minutes: 10 @@ -30,9 +48,124 @@ jobs: - name: Run Lint run: ./scripts/lint.sh --go-lint + format-solidity: + name: format solidity + runs-on: ubuntu-22.04 + timeout-minutes: 10 + + steps: + - name: Checkout repository and submodules + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Check Solidity Formatting + run: | + export PATH=$PATH:$HOME/.foundry/bin + ./scripts/lint.sh --sol-format-check + + protobuf-gen-check: + name: check protobuf generation + runs-on: ubuntu-22.04 + timeout-minutes: 10 + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + - name: Ensure protobuf changes are checked in run: | scripts/protobuf_codegen.sh git update-index --really-refresh >> /dev/null git diff-index HEAD # to show the differences git diff-index --quiet HEAD || (echo 'protobuf generated code changes have not all been checked in' && exit 1) + + codegen_check: + name: check code generation + runs-on: ubuntu-22.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: "go.mod" + + - name: Generate code + run: go generate ./... + + - name: Print diff + run: git --no-pager diff + + - name: Fail if diff exists + run: git --no-pager diff --quiet + + gomod_check: + name: Check go.mod + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v5 + with: + submodules: recursive + + - uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + + - run: go mod tidy + - run: git --no-pager diff -- go.mod go.sum # This prints the diff + - run: git --no-pager diff --quiet -- go.mod go.sum # This errors if there is a diff + + + abi_binding: + name: abi_binding + runs-on: ubuntu-22.04 + + steps: + - name: Checkout Repository + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: "go.mod" + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Install solc + run: | + source ./scripts/versions.sh + wget https://github.com/ethereum/solidity/releases/download/v$SOLIDITY_VERSION/solc-static-linux + chmod +x solc-static-linux + sudo mv solc-static-linux /usr/local/bin/solc + + - name: Generate ABI Go bindings + run: | + export PATH=$PATH:$HOME/.foundry/bin + export GOPATH=$HOME/go + export PATH="$PATH:$GOPATH/bin" + ./scripts/abi_bindings.sh + + - name: Print diff + run: git --no-pager diff -- abi-bindings/**.go + + - name: Fail if diff exists + run: git --no-pager diff --quiet -- abi-bindings/**.go \ No newline at end of file diff --git a/.github/workflows/mock_checker.yml b/.github/workflows/mock_checker.yml deleted file mode 100644 index 7a4fd50a7..000000000 --- a/.github/workflows/mock_checker.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Mock Checker - -on: - push: - branches: - - main - pull_request: - branches: - - "**" - -jobs: - generated_code: - name: generated_code - runs-on: ubuntu-22.04 - - steps: - - name: Checkout repository - uses: actions/checkout@v5 - with: - submodules: recursive - - - name: Setup Go - uses: actions/setup-go@v6 - with: - go-version-file: "go.mod" - - - name: Generate code - run: go generate ./... - - - name: Print diff - run: git --no-pager diff - - - name: Fail if diff exists - run: git --no-pager diff --quiet diff --git a/.github/workflows/e2e.yml b/.github/workflows/relayer_e2e.yml similarity index 96% rename from .github/workflows/e2e.yml rename to .github/workflows/relayer_e2e.yml index ce889cb2a..31ac02731 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/relayer_e2e.yml @@ -50,4 +50,4 @@ jobs: submodules: recursive - name: Run E2E Tests - run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh + run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/relayer_e2e_test.sh diff --git a/.github/workflows/release-teleporter.yml b/.github/workflows/release-teleporter.yml new file mode 100644 index 000000000..5bcb29fd5 --- /dev/null +++ b/.github/workflows/release-teleporter.yml @@ -0,0 +1,70 @@ +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +name: Release Teleporter + +on: + push: + tags: + - "teleporter-v[0-9].0.0" + +jobs: + build_and_upload_artifacts: + name: Build and Upload Teleporter Artifacts + runs-on: ubuntu-22.04 + env: + deployment_tx_fn: TeleporterMessenger_Deployment_Transaction_${{ github.ref_name }}.txt + deployer_addr_fn: TeleporterMessenger_Deployer_Address_${{ github.ref_name }}.txt + contract_addr_fn: TeleporterMessenger_Contract_Address_${{ github.ref_name }}.txt + teleporter_messenger_bytecode_fn: TeleporterMessenger_Bytecode_${{ github.ref_name }}.txt + teleporter_registry_bytecode_fn: TeleporterRegistry_Bytecode_${{ github.ref_name }}.txt + steps: + - name: Check out the repo + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: 'go.mod' + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Build Contracts + run: | + export PATH=$PATH:$HOME/.foundry/bin + forge build --force --extra-output-files bin + + - name: Build changelog + id: build_changelog + uses: mikepenz/release-changelog-builder-action@v5 + with: + failOnError: true + configuration: "./.github/changelog.json" + toTag: ${{ github.ref_name }} + + - name: Create Artifacts + id: artifacts + run: | + go run utils/contract-deployment/contractDeploymentTools.go constructKeylessTx out/TeleporterMessenger.sol/TeleporterMessenger.json + mv UniversalTeleporterDeployerTransaction.txt ${{ env.deployment_tx_fn }} + mv UniversalTeleporterDeployerAddress.txt ${{ env.deployer_addr_fn }} + mv UniversalTeleporterMessengerContractAddress.txt ${{ env.contract_addr_fn }} + mv out/TeleporterMessenger.sol/TeleporterMessenger.bin ${{ env.teleporter_messenger_bytecode_fn }} + mv out/TeleporterRegistry.sol/TeleporterRegistry.bin ${{ env.teleporter_registry_bytecode_fn }} + + - name: Create release + uses: softprops/action-gh-release@v2 + with: + name: ${{ github.ref_name }} + tag_name: ${{ github.ref_name }} + prerelease: false + body: ${{ steps.build_changelog.outputs.changelog }} + files: | + ${{ env.deployment_tx_fn }} + ${{ env.deployer_addr_fn }} + ${{ env.contract_addr_fn }} + ${{ env.teleporter_messenger_bytecode_fn }} + ${{ env.teleporter_registry_bytecode_fn}} diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 78d913660..46a06443d 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -6,6 +6,7 @@ on: pull_request: branches: - "dependabot/**" + jobs: semgrep: name: semgrep/ci diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml new file mode 100644 index 000000000..e908faba4 --- /dev/null +++ b/.github/workflows/slither.yml @@ -0,0 +1,45 @@ +name: Slither Analyze + +on: + push: + branches: + - main + pull_request: + branches: + - "**" + +jobs: + slither-analyze: + name: Slither Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Checkout repository and submodules + uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: 3.8 + + - name: Install Slither + run: | + pip install slither-analyzer + + - name: Install Foundry + run: ./scripts/install_foundry.sh + + - name: Run Slither + run: | + export PATH=$PATH:$HOME/.foundry/bin + slither ./ --fail-none --sarif ./results.sarif + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: results.sarif diff --git a/.gitignore b/.gitignore index a02f7777b..3a1c97c5a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,18 +2,56 @@ build/ __debug_bin tests/cmd/decider/decider +# miscellaneous +.idea/ +icm-contracts/contracts/pkg .vscode* relayer-config.json # Ginkgo test outputs -main.log -server.log +*.log *.test - # Release build outputs osxcross/ # Local DB .icm-relayer-storage/ + +# Forge output files +out/ +cache/ +target/ +bin/ +*/Cargo.lock + +# Binaries +icm-contracts/cmd/teleporter-cli/teleporter-cli + +# File generated by tests +icm-contracts/relayerConfig.json +icm-contracts/subnetGenesis_* +icm-contracts/vars.sh +icm-contracts/NETWORK_READY +icm-contracts/.awm-relayer-storage/ +icm-contracts/.icm-relayer-storage/ + +# Raw Contract Deployment Transaction +icm-contracts/UniversalTeleporterDeployerTransaction.txt +icm-contracts/UniversalTeleporterDeployerAddress.txt +icm-contracts/UniversalTeleporterMessengerContractAddress.txt + +# debug artifacts +*.debug.txt + +# Generated template files +icm-contracts/docker-compose-test-local.yml +icm-contracts/docker-compose-run-local.yml + +# Forge documentation +icm-contracts/docs/ +icm-contracts/coverage/ + +TeleporterRegistryAddress.json +ValidatorAddresses.json diff --git a/.gitmodules b/.gitmodules index ee2dcc15f..7d6b636a2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,7 @@ -[submodule "tests/contracts/lib/icm-contracts"] - path = tests/contracts/lib/icm-contracts - url = https://github.com/ava-labs/icm-contracts -[submodule "tests/contracts/lib/forge-std"] - path = tests/contracts/lib/forge-std +[submodule "icm-contracts/lib/forge-std"] + branch = v1 + path = icm-contracts/lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "icm-contracts/lib/openzeppelin-contracts-upgradeable"] + path = icm-contracts/lib/openzeppelin-contracts-upgradeable + url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 4895ef954..dccb9dcfb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -10,7 +10,7 @@ issues: # skip auto-generated files. exclude-files: - ".*mock.*" - - "tests/abi-bindings/.*" + - ".*/abi-bindings/.*" - ".*.pb.go" linters: diff --git a/.solhint.json b/.solhint.json new file mode 100644 index 000000000..de594e2a9 --- /dev/null +++ b/.solhint.json @@ -0,0 +1,50 @@ +{ + "extends": "solhint:recommended", + "rules": { + "compiler-version": [ + "error", + "0.8.25" + ], + "no-unused-vars": "error", + "func-visibility": [ + "error", + { + "ignoreConstructors": true + } + ], + "private-vars-leading-underscore": [ + "warn", + { + "strict": true + } + ], + "reason-string": [ + "warn", + { + "maxLength": 75 + } + ], + "gas-custom-errors": "off", + "ordering": "error", + "immutable-vars-naming": [ + "warn", + { + "immutablesAsConstants": false + } + ], + "func-named-parameters": [ + "error", + 5 + ], + "one-contract-per-file": "off", + "import-path-check": "off", + "gas-calldata-parameters": "off", + "use-natspec": "off", + "function-max-lines": "off", + "gas-indexed-events": "off", + "gas-increment-by-one": "off", + "gas-struct-packing": "off", + "gas-small-strings": "off", + "gas-strict-inequalities": "off" + } +} diff --git a/.solhintignore b/.solhintignore new file mode 100644 index 000000000..fd91ccb19 --- /dev/null +++ b/.solhintignore @@ -0,0 +1 @@ +icm-contracts/lib/ \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f710486e8..1da8e422e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ To start developing on ICM Services, you'll need Golang v1.22.10. - Run the unit tests ```sh -./scripts/test.sh +./scripts/unit-test.sh ``` ### Continuous Integration (CI) diff --git a/abi-bindings/go/OwnableUpgradeable/OwnableUpgradeable.go b/abi-bindings/go/OwnableUpgradeable/OwnableUpgradeable.go new file mode 100644 index 000000000..64c6b9340 --- /dev/null +++ b/abi-bindings/go/OwnableUpgradeable/OwnableUpgradeable.go @@ -0,0 +1,541 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ownableupgradeable + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// OwnableUpgradeableMetaData contains all meta data concerning the OwnableUpgradeable contract. +var OwnableUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// OwnableUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use OwnableUpgradeableMetaData.ABI instead. +var OwnableUpgradeableABI = OwnableUpgradeableMetaData.ABI + +// OwnableUpgradeable is an auto generated Go binding around an Ethereum contract. +type OwnableUpgradeable struct { + OwnableUpgradeableCaller // Read-only binding to the contract + OwnableUpgradeableTransactor // Write-only binding to the contract + OwnableUpgradeableFilterer // Log filterer for contract events +} + +// OwnableUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OwnableUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OwnableUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OwnableUpgradeableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OwnableUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type OwnableUpgradeableSession struct { + Contract *OwnableUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OwnableUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type OwnableUpgradeableCallerSession struct { + Contract *OwnableUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// OwnableUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type OwnableUpgradeableTransactorSession struct { + Contract *OwnableUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OwnableUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type OwnableUpgradeableRaw struct { + Contract *OwnableUpgradeable // Generic contract binding to access the raw methods on +} + +// OwnableUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCallerRaw struct { + Contract *OwnableUpgradeableCaller // Generic read-only contract binding to access the raw methods on +} + +// OwnableUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactorRaw struct { + Contract *OwnableUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewOwnableUpgradeable creates a new instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeable(address common.Address, backend bind.ContractBackend) (*OwnableUpgradeable, error) { + contract, err := bindOwnableUpgradeable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OwnableUpgradeable{OwnableUpgradeableCaller: OwnableUpgradeableCaller{contract: contract}, OwnableUpgradeableTransactor: OwnableUpgradeableTransactor{contract: contract}, OwnableUpgradeableFilterer: OwnableUpgradeableFilterer{contract: contract}}, nil +} + +// NewOwnableUpgradeableCaller creates a new read-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*OwnableUpgradeableCaller, error) { + contract, err := bindOwnableUpgradeable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OwnableUpgradeableCaller{contract: contract}, nil +} + +// NewOwnableUpgradeableTransactor creates a new write-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableUpgradeableTransactor, error) { + contract, err := bindOwnableUpgradeable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OwnableUpgradeableTransactor{contract: contract}, nil +} + +// NewOwnableUpgradeableFilterer creates a new log filterer instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableUpgradeableFilterer, error) { + contract, err := bindOwnableUpgradeable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OwnableUpgradeableFilterer{contract: contract}, nil +} + +// bindOwnableUpgradeable binds a generic wrapper to an already deployed contract. +func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OwnableUpgradeableMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.OwnableUpgradeableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OwnableUpgradeable *OwnableUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transact(opts, method, params...) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OwnableUpgradeable.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableCallerSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +} + +// OwnableUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitializedIterator struct { + Event *OwnableUpgradeableInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OwnableUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OwnableUpgradeableInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OwnableUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OwnableUpgradeableInitialized represents a Initialized event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*OwnableUpgradeableInitializedIterator, error) { + + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &OwnableUpgradeableInitializedIterator{contract: _OwnableUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableInitialized) (event.Subscription, error) { + + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseInitialized(log types.Log) (*OwnableUpgradeableInitialized, error) { + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// OwnableUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferredIterator struct { + Event *OwnableUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OwnableUpgradeableOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OwnableUpgradeableOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// OwnableUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableUpgradeableOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &OwnableUpgradeableOwnershipTransferredIterator{contract: _OwnableUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableUpgradeableOwnershipTransferred, error) { + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ProxyAdmin/ProxyAdmin.go b/abi-bindings/go/ProxyAdmin/ProxyAdmin.go new file mode 100644 index 000000000..761dc3a2a --- /dev/null +++ b/abi-bindings/go/ProxyAdmin/ProxyAdmin.go @@ -0,0 +1,481 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package proxyadmin + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ProxyAdminMetaData contains all meta data concerning the ProxyAdmin contract. +var ProxyAdminMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"UPGRADE_INTERFACE_VERSION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractITransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b506040516104fc3803806104fc83398101604081905261002e916100bb565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b6100658161006c565b50506100e8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f602082840312156100cb575f80fd5b81516001600160a01b03811681146100e1575f80fd5b9392505050565b610407806100f55f395ff3fe608060405260043610610049575f3560e01c8063715018a61461004d5780638da5cb5b146100635780639623609d1461008e578063ad3cb1cc146100a1578063f2fde38b146100de575b5f80fd5b348015610058575f80fd5b506100616100fd565b005b34801561006e575f80fd5b505f546040516001600160a01b0390911681526020015b60405180910390f35b61006161009c366004610260565b610110565b3480156100ac575f80fd5b506100d1604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516100859190610372565b3480156100e9575f80fd5b506100616100f836600461038b565b61017b565b6101056101bd565b61010e5f6101e9565b565b6101186101bd565b60405163278f794360e11b81526001600160a01b03841690634f1ef28690349061014890869086906004016103a6565b5f604051808303818588803b15801561015f575f80fd5b505af1158015610171573d5f803e3d5ffd5b5050505050505050565b6101836101bd565b6001600160a01b0381166101b157604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6101ba816101e9565b50565b5f546001600160a01b0316331461010e5760405163118cdaa760e01b81523360048201526024016101a8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146101ba575f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f805f60608486031215610272575f80fd5b833561027d81610238565b9250602084013561028d81610238565b9150604084013567ffffffffffffffff808211156102a9575f80fd5b818601915086601f8301126102bc575f80fd5b8135818111156102ce576102ce61024c565b604051601f8201601f19908116603f011681019083821181831017156102f6576102f661024c565b8160405282815289602084870101111561030e575f80fd5b826020860160208301375f6020848301015280955050505050509250925092565b5f81518084525f5b8181101561035357602081850181015186830182015201610337565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610384602083018461032f565b9392505050565b5f6020828403121561039b575f80fd5b813561038481610238565b6001600160a01b03831681526040602082018190525f906103c99083018461032f565b94935050505056fea26469706673582212209a89b9643439de81402f577cc04c9f6e18306877d7428ff9ace01d007bc8ab8964736f6c63430008190033", +} + +// ProxyAdminABI is the input ABI used to generate the binding from. +// Deprecated: Use ProxyAdminMetaData.ABI instead. +var ProxyAdminABI = ProxyAdminMetaData.ABI + +// ProxyAdminBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ProxyAdminMetaData.Bin instead. +var ProxyAdminBin = ProxyAdminMetaData.Bin + +// DeployProxyAdmin deploys a new Ethereum contract, binding an instance of ProxyAdmin to it. +func DeployProxyAdmin(auth *bind.TransactOpts, backend bind.ContractBackend, initialOwner common.Address) (common.Address, *types.Transaction, *ProxyAdmin, error) { + parsed, err := ProxyAdminMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ProxyAdminBin), backend, initialOwner) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ProxyAdmin{ProxyAdminCaller: ProxyAdminCaller{contract: contract}, ProxyAdminTransactor: ProxyAdminTransactor{contract: contract}, ProxyAdminFilterer: ProxyAdminFilterer{contract: contract}}, nil +} + +// ProxyAdmin is an auto generated Go binding around an Ethereum contract. +type ProxyAdmin struct { + ProxyAdminCaller // Read-only binding to the contract + ProxyAdminTransactor // Write-only binding to the contract + ProxyAdminFilterer // Log filterer for contract events +} + +// ProxyAdminCaller is an auto generated read-only Go binding around an Ethereum contract. +type ProxyAdminCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyAdminTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ProxyAdminTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyAdminFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ProxyAdminFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyAdminSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ProxyAdminSession struct { + Contract *ProxyAdmin // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ProxyAdminCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ProxyAdminCallerSession struct { + Contract *ProxyAdminCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ProxyAdminTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ProxyAdminTransactorSession struct { + Contract *ProxyAdminTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ProxyAdminRaw is an auto generated low-level Go binding around an Ethereum contract. +type ProxyAdminRaw struct { + Contract *ProxyAdmin // Generic contract binding to access the raw methods on +} + +// ProxyAdminCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ProxyAdminCallerRaw struct { + Contract *ProxyAdminCaller // Generic read-only contract binding to access the raw methods on +} + +// ProxyAdminTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ProxyAdminTransactorRaw struct { + Contract *ProxyAdminTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewProxyAdmin creates a new instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdmin(address common.Address, backend bind.ContractBackend) (*ProxyAdmin, error) { + contract, err := bindProxyAdmin(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ProxyAdmin{ProxyAdminCaller: ProxyAdminCaller{contract: contract}, ProxyAdminTransactor: ProxyAdminTransactor{contract: contract}, ProxyAdminFilterer: ProxyAdminFilterer{contract: contract}}, nil +} + +// NewProxyAdminCaller creates a new read-only instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdminCaller(address common.Address, caller bind.ContractCaller) (*ProxyAdminCaller, error) { + contract, err := bindProxyAdmin(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ProxyAdminCaller{contract: contract}, nil +} + +// NewProxyAdminTransactor creates a new write-only instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdminTransactor(address common.Address, transactor bind.ContractTransactor) (*ProxyAdminTransactor, error) { + contract, err := bindProxyAdmin(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ProxyAdminTransactor{contract: contract}, nil +} + +// NewProxyAdminFilterer creates a new log filterer instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdminFilterer(address common.Address, filterer bind.ContractFilterer) (*ProxyAdminFilterer, error) { + contract, err := bindProxyAdmin(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ProxyAdminFilterer{contract: contract}, nil +} + +// bindProxyAdmin binds a generic wrapper to an already deployed contract. +func bindProxyAdmin(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ProxyAdminMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ProxyAdmin *ProxyAdminRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ProxyAdmin.Contract.ProxyAdminCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ProxyAdmin *ProxyAdminRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProxyAdmin.Contract.ProxyAdminTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ProxyAdmin *ProxyAdminRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ProxyAdmin.Contract.ProxyAdminTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ProxyAdmin *ProxyAdminCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ProxyAdmin.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ProxyAdmin *ProxyAdminTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProxyAdmin.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ProxyAdmin *ProxyAdminTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ProxyAdmin.Contract.contract.Transact(opts, method, params...) +} + +// UPGRADEINTERFACEVERSION is a free data retrieval call binding the contract method 0xad3cb1cc. +// +// Solidity: function UPGRADE_INTERFACE_VERSION() view returns(string) +func (_ProxyAdmin *ProxyAdminCaller) UPGRADEINTERFACEVERSION(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ProxyAdmin.contract.Call(opts, &out, "UPGRADE_INTERFACE_VERSION") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// UPGRADEINTERFACEVERSION is a free data retrieval call binding the contract method 0xad3cb1cc. +// +// Solidity: function UPGRADE_INTERFACE_VERSION() view returns(string) +func (_ProxyAdmin *ProxyAdminSession) UPGRADEINTERFACEVERSION() (string, error) { + return _ProxyAdmin.Contract.UPGRADEINTERFACEVERSION(&_ProxyAdmin.CallOpts) +} + +// UPGRADEINTERFACEVERSION is a free data retrieval call binding the contract method 0xad3cb1cc. +// +// Solidity: function UPGRADE_INTERFACE_VERSION() view returns(string) +func (_ProxyAdmin *ProxyAdminCallerSession) UPGRADEINTERFACEVERSION() (string, error) { + return _ProxyAdmin.Contract.UPGRADEINTERFACEVERSION(&_ProxyAdmin.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ProxyAdmin *ProxyAdminCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ProxyAdmin.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ProxyAdmin *ProxyAdminSession) Owner() (common.Address, error) { + return _ProxyAdmin.Contract.Owner(&_ProxyAdmin.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ProxyAdmin *ProxyAdminCallerSession) Owner() (common.Address, error) { + return _ProxyAdmin.Contract.Owner(&_ProxyAdmin.CallOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ProxyAdmin *ProxyAdminTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProxyAdmin.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ProxyAdmin *ProxyAdminSession) RenounceOwnership() (*types.Transaction, error) { + return _ProxyAdmin.Contract.RenounceOwnership(&_ProxyAdmin.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ProxyAdmin *ProxyAdminTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ProxyAdmin.Contract.RenounceOwnership(&_ProxyAdmin.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ProxyAdmin *ProxyAdminTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ProxyAdmin.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ProxyAdmin *ProxyAdminSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ProxyAdmin.Contract.TransferOwnership(&_ProxyAdmin.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ProxyAdmin *ProxyAdminTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ProxyAdmin.Contract.TransferOwnership(&_ProxyAdmin.TransactOpts, newOwner) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_ProxyAdmin *ProxyAdminTransactor) UpgradeAndCall(opts *bind.TransactOpts, proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _ProxyAdmin.contract.Transact(opts, "upgradeAndCall", proxy, implementation, data) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_ProxyAdmin *ProxyAdminSession) UpgradeAndCall(proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _ProxyAdmin.Contract.UpgradeAndCall(&_ProxyAdmin.TransactOpts, proxy, implementation, data) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_ProxyAdmin *ProxyAdminTransactorSession) UpgradeAndCall(proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _ProxyAdmin.Contract.UpgradeAndCall(&_ProxyAdmin.TransactOpts, proxy, implementation, data) +} + +// ProxyAdminOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ProxyAdmin contract. +type ProxyAdminOwnershipTransferredIterator struct { + Event *ProxyAdminOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ProxyAdminOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ProxyAdminOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ProxyAdminOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ProxyAdminOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProxyAdminOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProxyAdminOwnershipTransferred represents a OwnershipTransferred event raised by the ProxyAdmin contract. +type ProxyAdminOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ProxyAdmin *ProxyAdminFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ProxyAdminOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ProxyAdmin.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ProxyAdminOwnershipTransferredIterator{contract: _ProxyAdmin.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ProxyAdmin *ProxyAdminFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ProxyAdminOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ProxyAdmin.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ProxyAdminOwnershipTransferred) + if err := _ProxyAdmin.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ProxyAdmin *ProxyAdminFilterer) ParseOwnershipTransferred(log types.Log) (*ProxyAdminOwnershipTransferred, error) { + event := new(ProxyAdminOwnershipTransferred) + if err := _ProxyAdmin.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/TransparentUpgradeableProxy/TransparentUpgradeableProxy.go b/abi-bindings/go/TransparentUpgradeableProxy/TransparentUpgradeableProxy.go new file mode 100644 index 000000000..77fe6bf52 --- /dev/null +++ b/abi-bindings/go/TransparentUpgradeableProxy/TransparentUpgradeableProxy.go @@ -0,0 +1,503 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package transparentupgradeableproxy + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TransparentUpgradeableProxyMetaData contains all meta data concerning the TransparentUpgradeableProxy contract. +var TransparentUpgradeableProxyMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"ERC1967InvalidAdmin\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"ERC1967InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ERC1967NonPayable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProxyDeniedAdminAccess\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"}]", + Bin: "0x60a0604052604051610e0d380380610e0d8339810160408190526100229161038c565b828161002e828261008c565b50508160405161003d9061032e565b6001600160a01b039091168152602001604051809103905ff080158015610066573d5f803e3d5ffd5b506001600160a01b031660805261008461007f60805190565b6100ea565b505050610471565b61009582610157565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156100de576100d982826101d5565b505050565b6100e6610248565b5050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6101295f80516020610ded833981519152546001600160a01b031690565b604080516001600160a01b03928316815291841660208301520160405180910390a161015481610269565b50565b806001600160a01b03163b5f0361019157604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b60605f80846001600160a01b0316846040516101f19190610456565b5f60405180830381855af49150503d805f8114610229576040519150601f19603f3d011682016040523d82523d5f602084013e61022e565b606091505b50909250905061023f8583836102a6565b95945050505050565b34156102675760405163b398979f60e01b815260040160405180910390fd5b565b6001600160a01b03811661029257604051633173bdd160e11b81525f6004820152602401610188565b805f80516020610ded8339815191526101b4565b6060826102bb576102b682610305565b6102fe565b81511580156102d257506001600160a01b0384163b155b156102fb57604051639996b31560e01b81526001600160a01b0385166004820152602401610188565b50805b9392505050565b8051156103155780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6104fc806108f183390190565b80516001600160a01b0381168114610351575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f5b8381101561038457818101518382015260200161036c565b50505f910152565b5f805f6060848603121561039e575f80fd5b6103a78461033b565b92506103b56020850161033b565b60408501519092506001600160401b03808211156103d1575f80fd5b818601915086601f8301126103e4575f80fd5b8151818111156103f6576103f6610356565b604051601f8201601f19908116603f0116810190838211818310171561041e5761041e610356565b81604052828152896020848701011115610436575f80fd5b61044783602083016020880161036a565b80955050505050509250925092565b5f825161046781846020870161036a565b9190910192915050565b6080516104696104885f395f601001526104695ff3fe608060405261000c61000e565b005b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361007a575f356001600160e01b03191663278f794360e11b14610070576040516334ad5dbb60e21b815260040160405180910390fd5b610078610082565b565b6100786100b0565b5f806100913660048184610303565b81019061009e919061033e565b915091506100ac82826100c0565b5050565b6100786100bb61011a565b610151565b6100c98261016f565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156101125761010d82826101ea565b505050565b6100ac61025c565b5f61014c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f80375f80365f845af43d5f803e80801561016b573d5ff35b3d5ffd5b806001600160a01b03163b5f036101a957604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b0316846040516102069190610407565b5f60405180830381855af49150503d805f811461023e576040519150601f19603f3d011682016040523d82523d5f602084013e610243565b606091505b509150915061025385838361027b565b95945050505050565b34156100785760405163b398979f60e01b815260040160405180910390fd5b6060826102905761028b826102da565b6102d3565b81511580156102a757506001600160a01b0384163b155b156102d057604051639996b31560e01b81526001600160a01b03851660048201526024016101a0565b50805b9392505050565b8051156102ea5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f8085851115610311575f80fd5b8386111561031d575f80fd5b5050820193919092039150565b634e487b7160e01b5f52604160045260245ffd5b5f806040838503121561034f575f80fd5b82356001600160a01b0381168114610365575f80fd5b9150602083013567ffffffffffffffff80821115610381575f80fd5b818501915085601f830112610394575f80fd5b8135818111156103a6576103a661032a565b604051601f8201601f19908116603f011681019083821181831017156103ce576103ce61032a565b816040528281528860208487010111156103e6575f80fd5b826020860160208301375f6020848301015280955050505050509250929050565b5f82515f5b81811015610426576020818601810151858301520161040c565b505f92019182525091905056fea2646970667358221220cc0564ccb76f4f4808826b6e7332512d2fd23cba5d649265e2188a5f9d7b431964736f6c63430008190033608060405234801561000f575f80fd5b506040516104fc3803806104fc83398101604081905261002e916100bb565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b6100658161006c565b50506100e8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f602082840312156100cb575f80fd5b81516001600160a01b03811681146100e1575f80fd5b9392505050565b610407806100f55f395ff3fe608060405260043610610049575f3560e01c8063715018a61461004d5780638da5cb5b146100635780639623609d1461008e578063ad3cb1cc146100a1578063f2fde38b146100de575b5f80fd5b348015610058575f80fd5b506100616100fd565b005b34801561006e575f80fd5b505f546040516001600160a01b0390911681526020015b60405180910390f35b61006161009c366004610260565b610110565b3480156100ac575f80fd5b506100d1604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516100859190610372565b3480156100e9575f80fd5b506100616100f836600461038b565b61017b565b6101056101bd565b61010e5f6101e9565b565b6101186101bd565b60405163278f794360e11b81526001600160a01b03841690634f1ef28690349061014890869086906004016103a6565b5f604051808303818588803b15801561015f575f80fd5b505af1158015610171573d5f803e3d5ffd5b5050505050505050565b6101836101bd565b6001600160a01b0381166101b157604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6101ba816101e9565b50565b5f546001600160a01b0316331461010e5760405163118cdaa760e01b81523360048201526024016101a8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146101ba575f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f805f60608486031215610272575f80fd5b833561027d81610238565b9250602084013561028d81610238565b9150604084013567ffffffffffffffff808211156102a9575f80fd5b818601915086601f8301126102bc575f80fd5b8135818111156102ce576102ce61024c565b604051601f8201601f19908116603f011681019083821181831017156102f6576102f661024c565b8160405282815289602084870101111561030e575f80fd5b826020860160208301375f6020848301015280955050505050509250925092565b5f81518084525f5b8181101561035357602081850181015186830182015201610337565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610384602083018461032f565b9392505050565b5f6020828403121561039b575f80fd5b813561038481610238565b6001600160a01b03831681526040602082018190525f906103c99083018461032f565b94935050505056fea26469706673582212209a89b9643439de81402f577cc04c9f6e18306877d7428ff9ace01d007bc8ab8964736f6c63430008190033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", +} + +// TransparentUpgradeableProxyABI is the input ABI used to generate the binding from. +// Deprecated: Use TransparentUpgradeableProxyMetaData.ABI instead. +var TransparentUpgradeableProxyABI = TransparentUpgradeableProxyMetaData.ABI + +// TransparentUpgradeableProxyBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TransparentUpgradeableProxyMetaData.Bin instead. +var TransparentUpgradeableProxyBin = TransparentUpgradeableProxyMetaData.Bin + +// DeployTransparentUpgradeableProxy deploys a new Ethereum contract, binding an instance of TransparentUpgradeableProxy to it. +func DeployTransparentUpgradeableProxy(auth *bind.TransactOpts, backend bind.ContractBackend, _logic common.Address, initialOwner common.Address, _data []byte) (common.Address, *types.Transaction, *TransparentUpgradeableProxy, error) { + parsed, err := TransparentUpgradeableProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TransparentUpgradeableProxyBin), backend, _logic, initialOwner, _data) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TransparentUpgradeableProxy{TransparentUpgradeableProxyCaller: TransparentUpgradeableProxyCaller{contract: contract}, TransparentUpgradeableProxyTransactor: TransparentUpgradeableProxyTransactor{contract: contract}, TransparentUpgradeableProxyFilterer: TransparentUpgradeableProxyFilterer{contract: contract}}, nil +} + +// TransparentUpgradeableProxy is an auto generated Go binding around an Ethereum contract. +type TransparentUpgradeableProxy struct { + TransparentUpgradeableProxyCaller // Read-only binding to the contract + TransparentUpgradeableProxyTransactor // Write-only binding to the contract + TransparentUpgradeableProxyFilterer // Log filterer for contract events +} + +// TransparentUpgradeableProxyCaller is an auto generated read-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentUpgradeableProxyTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentUpgradeableProxyFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TransparentUpgradeableProxyFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentUpgradeableProxySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TransparentUpgradeableProxySession struct { + Contract *TransparentUpgradeableProxy // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TransparentUpgradeableProxyCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TransparentUpgradeableProxyCallerSession struct { + Contract *TransparentUpgradeableProxyCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TransparentUpgradeableProxyTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TransparentUpgradeableProxyTransactorSession struct { + Contract *TransparentUpgradeableProxyTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TransparentUpgradeableProxyRaw is an auto generated low-level Go binding around an Ethereum contract. +type TransparentUpgradeableProxyRaw struct { + Contract *TransparentUpgradeableProxy // Generic contract binding to access the raw methods on +} + +// TransparentUpgradeableProxyCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyCallerRaw struct { + Contract *TransparentUpgradeableProxyCaller // Generic read-only contract binding to access the raw methods on +} + +// TransparentUpgradeableProxyTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyTransactorRaw struct { + Contract *TransparentUpgradeableProxyTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTransparentUpgradeableProxy creates a new instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxy(address common.Address, backend bind.ContractBackend) (*TransparentUpgradeableProxy, error) { + contract, err := bindTransparentUpgradeableProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxy{TransparentUpgradeableProxyCaller: TransparentUpgradeableProxyCaller{contract: contract}, TransparentUpgradeableProxyTransactor: TransparentUpgradeableProxyTransactor{contract: contract}, TransparentUpgradeableProxyFilterer: TransparentUpgradeableProxyFilterer{contract: contract}}, nil +} + +// NewTransparentUpgradeableProxyCaller creates a new read-only instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxyCaller(address common.Address, caller bind.ContractCaller) (*TransparentUpgradeableProxyCaller, error) { + contract, err := bindTransparentUpgradeableProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyCaller{contract: contract}, nil +} + +// NewTransparentUpgradeableProxyTransactor creates a new write-only instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*TransparentUpgradeableProxyTransactor, error) { + contract, err := bindTransparentUpgradeableProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyTransactor{contract: contract}, nil +} + +// NewTransparentUpgradeableProxyFilterer creates a new log filterer instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*TransparentUpgradeableProxyFilterer, error) { + contract, err := bindTransparentUpgradeableProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyFilterer{contract: contract}, nil +} + +// bindTransparentUpgradeableProxy binds a generic wrapper to an already deployed contract. +func bindTransparentUpgradeableProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TransparentUpgradeableProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TransparentUpgradeableProxy.Contract.TransparentUpgradeableProxyCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.TransparentUpgradeableProxyTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.TransparentUpgradeableProxyTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TransparentUpgradeableProxy.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.contract.Transact(opts, method, params...) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxySession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.Fallback(&_TransparentUpgradeableProxy.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.Fallback(&_TransparentUpgradeableProxy.TransactOpts, calldata) +} + +// TransparentUpgradeableProxyAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyAdminChangedIterator struct { + Event *TransparentUpgradeableProxyAdminChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TransparentUpgradeableProxyAdminChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyAdminChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyAdminChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TransparentUpgradeableProxyAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TransparentUpgradeableProxyAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TransparentUpgradeableProxyAdminChanged represents a AdminChanged event raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*TransparentUpgradeableProxyAdminChangedIterator, error) { + + logs, sub, err := _TransparentUpgradeableProxy.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyAdminChangedIterator{contract: _TransparentUpgradeableProxy.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *TransparentUpgradeableProxyAdminChanged) (event.Subscription, error) { + + logs, sub, err := _TransparentUpgradeableProxy.contract.WatchLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TransparentUpgradeableProxyAdminChanged) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "AdminChanged", 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 +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) ParseAdminChanged(log types.Log) (*TransparentUpgradeableProxyAdminChanged, error) { + event := new(TransparentUpgradeableProxyAdminChanged) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TransparentUpgradeableProxyUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyUpgradedIterator struct { + Event *TransparentUpgradeableProxyUpgraded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TransparentUpgradeableProxyUpgradedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyUpgraded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyUpgraded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TransparentUpgradeableProxyUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TransparentUpgradeableProxyUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TransparentUpgradeableProxyUpgraded represents a Upgraded event raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*TransparentUpgradeableProxyUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TransparentUpgradeableProxy.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyUpgradedIterator{contract: _TransparentUpgradeableProxy.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *TransparentUpgradeableProxyUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TransparentUpgradeableProxy.contract.WatchLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TransparentUpgradeableProxyUpgraded) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "Upgraded", 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 +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) ParseUpgraded(log types.Log) (*TransparentUpgradeableProxyUpgraded, error) { + event := new(TransparentUpgradeableProxyUpgraded) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/governance/ValidatorSetSig/ValidatorSetSig.go b/abi-bindings/go/governance/ValidatorSetSig/ValidatorSetSig.go new file mode 100644 index 000000000..bef5e9053 --- /dev/null +++ b/abi-bindings/go/governance/ValidatorSetSig/ValidatorSetSig.go @@ -0,0 +1,592 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package validatorsetsig + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ValidatorSetSigMessage is an auto generated low-level Go binding around an user-defined struct. +type ValidatorSetSigMessage struct { + TargetBlockchainID [32]byte + ValidatorSetSigAddress common.Address + TargetContractAddress common.Address + Nonce *big.Int + Value *big.Int + Payload []byte +} + +// ValidatorSetSigMetaData contains all meta data concerning the ValidatorSetSig contract. +var ValidatorSetSigMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validatorBlockchainID_\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"targetContractAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"Delivered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VALIDATORS_SOURCE_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WARP_MESSENGER\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"executeCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"targetContractAddress\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"targetBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"validatorSetSigAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"targetContractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"internalType\":\"structValidatorSetSigMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"validateMessage\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"validatorBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60c060405234801561000f575f80fd5b50604051610b76380380610b7683398101604081905261002e916100b2565b60015f5560808190526040805163084279ef60e31b8152905173020000000000000000000000000000000000000591634213cf789160048083019260209291908290030181865afa158015610085573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100a991906100b2565b60a052506100c9565b5f602082840312156100c2575f80fd5b5051919050565b60805160a051610a7e6100f85f395f818161017701526104ba01525f818161012a01526102790152610a7e5ff3fe608060405260043610610071575f3560e01c80637ecebe001161004c5780637ecebe00146100e05780638d6e579d14610119578063b771b3bc1461014c578063d127dc9b14610166575f80fd5b80630731775d1461007c5780635433da42146100ac5780637d969c34146100c1575f80fd5b3661007857005b5f80fd5b348015610087575f80fd5b5061008f5f81565b6040516001600160a01b0390911681526020015b60405180910390f35b6100bf6100ba366004610642565b610199565b005b3480156100cc575f80fd5b506100bf6100db36600461079a565b6104b6565b3480156100eb575f80fd5b5061010b6100fa366004610842565b60016020525f908152604090205481565b6040519081526020016100a3565b348015610124575f80fd5b5061010b7f000000000000000000000000000000000000000000000000000000000000000081565b348015610157575f80fd5b5061008f6005600160991b0181565b348015610171575f80fd5b5061010b7f000000000000000000000000000000000000000000000000000000000000000081565b6101a161061a565b6040516306f8253560e41b815263ffffffff821660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa1580156101ea573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261021191908101906108c9565b91509150806102755760405162461bcd60e51b815260206004820152602560248201527f56616c696461746f725365745369673a20696e76616c69642077617270206d65604482015264737361676560d81b60648201526084015b60405180910390fd5b81517f0000000000000000000000000000000000000000000000000000000000000000146102f45760405162461bcd60e51b815260206004820152602660248201527f56616c696461746f725365745369673a20696e76616c696420736f75726365436044820152651a185a5b925160d21b606482015260840161026c565b60208201516001600160a01b0316156103655760405162461bcd60e51b815260206004820152602d60248201527f56616c696461746f725365745369673a206e6f6e2d7a65726f206f726967696e60448201526c53656e6465724164647265737360981b606482015260840161026c565b5f826040015180602001905181019061037e9190610969565b9050610389816104b6565b6060810151610399906001610a08565b604080830180516001600160a01b039081165f9081526001602052838120949094559051608085015160a0860151935191909216926103d791610a2d565b5f6040518083038185875af1925050503d805f8114610411576040519150601f19603f3d011682016040523d82523d5f602084013e610416565b606091505b50509050806104675760405162461bcd60e51b815260206004820152601c60248201527f56616c696461746f725365745369673a2063616c6c206661696c656400000000604482015260640161026c565b816060015182604001516001600160a01b03167f5942a9a3968c7d49fc51c027041544ea295f5c1e395d6d8aa35c4369959f8ed960405160405180910390a3505050506104b360015f55565b50565b80517f00000000000000000000000000000000000000000000000000000000000000001461053a5760405162461bcd60e51b815260206004820152602b60248201527f56616c696461746f725365745369673a20696e76616c6964207461726765744260448201526a1b1bd8dad8da185a5b925160aa1b606482015260840161026c565b60208101516001600160a01b031630146105ae5760405162461bcd60e51b815260206004820152602f60248201527f56616c696461746f725365745369673a20696e76616c69642076616c6964617460448201526e6f725365745369674164647265737360881b606482015260840161026c565b60608101516040808301516001600160a01b03165f90815260016020522054146104b35760405162461bcd60e51b815260206004820152601e60248201527f56616c696461746f725365745369673a20696e76616c6964206e6f6e63650000604482015260640161026c565b60025f540361063c57604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b5f60208284031215610652575f80fd5b813563ffffffff81168114610665575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b60405160c0810167ffffffffffffffff811182821017156106a3576106a361066c565b60405290565b6040516060810167ffffffffffffffff811182821017156106a3576106a361066c565b604051601f8201601f1916810167ffffffffffffffff811182821017156106f5576106f561066c565b604052919050565b6001600160a01b03811681146104b3575f80fd5b803561071c816106fd565b919050565b5f67ffffffffffffffff82111561073a5761073a61066c565b50601f01601f191660200190565b5f82601f830112610757575f80fd5b813561076a61076582610721565b6106cc565b81815284602083860101111561077e575f80fd5b816020850160208301375f918101602001919091529392505050565b5f602082840312156107aa575f80fd5b813567ffffffffffffffff808211156107c1575f80fd5b9083019060c082860312156107d4575f80fd5b6107dc610680565b823581526107ec60208401610711565b60208201526107fd60408401610711565b6040820152606083013560608201526080830135608082015260a083013582811115610827575f80fd5b61083387828601610748565b60a08301525095945050505050565b5f60208284031215610852575f80fd5b8135610665816106fd565b5f5b8381101561087757818101518382015260200161085f565b50505f910152565b5f82601f83011261088e575f80fd5b815161089c61076582610721565b8181528460208386010111156108b0575f80fd5b6108c182602083016020870161085d565b949350505050565b5f80604083850312156108da575f80fd5b825167ffffffffffffffff808211156108f1575f80fd5b9084019060608287031215610904575f80fd5b61090c6106a9565b82518152602083015161091e816106fd565b6020820152604083015182811115610934575f80fd5b6109408882860161087f565b6040830152508094505050506020830151801515811461095e575f80fd5b809150509250929050565b5f60208284031215610979575f80fd5b815167ffffffffffffffff80821115610990575f80fd5b9083019060c082860312156109a3575f80fd5b6109ab610680565b8251815260208301516109bd816106fd565b602082015260408301516109d0816106fd565b80604083015250606083015160608201526080830151608082015260a0830151828111156109fc575f80fd5b6108338782860161087f565b80820180821115610a2757634e487b7160e01b5f52601160045260245ffd5b92915050565b5f8251610a3e81846020870161085d565b919091019291505056fea26469706673582212204f1a917968b1936d05698b951005ca3e11c79481f2ff4b21123543414c89c7f064736f6c63430008190033", +} + +// ValidatorSetSigABI is the input ABI used to generate the binding from. +// Deprecated: Use ValidatorSetSigMetaData.ABI instead. +var ValidatorSetSigABI = ValidatorSetSigMetaData.ABI + +// ValidatorSetSigBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ValidatorSetSigMetaData.Bin instead. +var ValidatorSetSigBin = ValidatorSetSigMetaData.Bin + +// DeployValidatorSetSig deploys a new Ethereum contract, binding an instance of ValidatorSetSig to it. +func DeployValidatorSetSig(auth *bind.TransactOpts, backend bind.ContractBackend, validatorBlockchainID_ [32]byte) (common.Address, *types.Transaction, *ValidatorSetSig, error) { + parsed, err := ValidatorSetSigMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ValidatorSetSigBin), backend, validatorBlockchainID_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ValidatorSetSig{ValidatorSetSigCaller: ValidatorSetSigCaller{contract: contract}, ValidatorSetSigTransactor: ValidatorSetSigTransactor{contract: contract}, ValidatorSetSigFilterer: ValidatorSetSigFilterer{contract: contract}}, nil +} + +// ValidatorSetSig is an auto generated Go binding around an Ethereum contract. +type ValidatorSetSig struct { + ValidatorSetSigCaller // Read-only binding to the contract + ValidatorSetSigTransactor // Write-only binding to the contract + ValidatorSetSigFilterer // Log filterer for contract events +} + +// ValidatorSetSigCaller is an auto generated read-only Go binding around an Ethereum contract. +type ValidatorSetSigCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorSetSigTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ValidatorSetSigTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorSetSigFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ValidatorSetSigFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorSetSigSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ValidatorSetSigSession struct { + Contract *ValidatorSetSig // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorSetSigCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ValidatorSetSigCallerSession struct { + Contract *ValidatorSetSigCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ValidatorSetSigTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ValidatorSetSigTransactorSession struct { + Contract *ValidatorSetSigTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorSetSigRaw is an auto generated low-level Go binding around an Ethereum contract. +type ValidatorSetSigRaw struct { + Contract *ValidatorSetSig // Generic contract binding to access the raw methods on +} + +// ValidatorSetSigCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ValidatorSetSigCallerRaw struct { + Contract *ValidatorSetSigCaller // Generic read-only contract binding to access the raw methods on +} + +// ValidatorSetSigTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ValidatorSetSigTransactorRaw struct { + Contract *ValidatorSetSigTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewValidatorSetSig creates a new instance of ValidatorSetSig, bound to a specific deployed contract. +func NewValidatorSetSig(address common.Address, backend bind.ContractBackend) (*ValidatorSetSig, error) { + contract, err := bindValidatorSetSig(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ValidatorSetSig{ValidatorSetSigCaller: ValidatorSetSigCaller{contract: contract}, ValidatorSetSigTransactor: ValidatorSetSigTransactor{contract: contract}, ValidatorSetSigFilterer: ValidatorSetSigFilterer{contract: contract}}, nil +} + +// NewValidatorSetSigCaller creates a new read-only instance of ValidatorSetSig, bound to a specific deployed contract. +func NewValidatorSetSigCaller(address common.Address, caller bind.ContractCaller) (*ValidatorSetSigCaller, error) { + contract, err := bindValidatorSetSig(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ValidatorSetSigCaller{contract: contract}, nil +} + +// NewValidatorSetSigTransactor creates a new write-only instance of ValidatorSetSig, bound to a specific deployed contract. +func NewValidatorSetSigTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorSetSigTransactor, error) { + contract, err := bindValidatorSetSig(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ValidatorSetSigTransactor{contract: contract}, nil +} + +// NewValidatorSetSigFilterer creates a new log filterer instance of ValidatorSetSig, bound to a specific deployed contract. +func NewValidatorSetSigFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorSetSigFilterer, error) { + contract, err := bindValidatorSetSig(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ValidatorSetSigFilterer{contract: contract}, nil +} + +// bindValidatorSetSig binds a generic wrapper to an already deployed contract. +func bindValidatorSetSig(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ValidatorSetSigMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorSetSig *ValidatorSetSigRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorSetSig.Contract.ValidatorSetSigCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorSetSig *ValidatorSetSigRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorSetSig.Contract.ValidatorSetSigTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorSetSig *ValidatorSetSigRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorSetSig.Contract.ValidatorSetSigTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorSetSig *ValidatorSetSigCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorSetSig.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorSetSig *ValidatorSetSigTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorSetSig.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorSetSig *ValidatorSetSigTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorSetSig.Contract.contract.Transact(opts, method, params...) +} + +// VALIDATORSSOURCEADDRESS is a free data retrieval call binding the contract method 0x0731775d. +// +// Solidity: function VALIDATORS_SOURCE_ADDRESS() view returns(address) +func (_ValidatorSetSig *ValidatorSetSigCaller) VALIDATORSSOURCEADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ValidatorSetSig.contract.Call(opts, &out, "VALIDATORS_SOURCE_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// VALIDATORSSOURCEADDRESS is a free data retrieval call binding the contract method 0x0731775d. +// +// Solidity: function VALIDATORS_SOURCE_ADDRESS() view returns(address) +func (_ValidatorSetSig *ValidatorSetSigSession) VALIDATORSSOURCEADDRESS() (common.Address, error) { + return _ValidatorSetSig.Contract.VALIDATORSSOURCEADDRESS(&_ValidatorSetSig.CallOpts) +} + +// VALIDATORSSOURCEADDRESS is a free data retrieval call binding the contract method 0x0731775d. +// +// Solidity: function VALIDATORS_SOURCE_ADDRESS() view returns(address) +func (_ValidatorSetSig *ValidatorSetSigCallerSession) VALIDATORSSOURCEADDRESS() (common.Address, error) { + return _ValidatorSetSig.Contract.VALIDATORSSOURCEADDRESS(&_ValidatorSetSig.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ValidatorSetSig *ValidatorSetSigCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ValidatorSetSig.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ValidatorSetSig *ValidatorSetSigSession) WARPMESSENGER() (common.Address, error) { + return _ValidatorSetSig.Contract.WARPMESSENGER(&_ValidatorSetSig.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ValidatorSetSig *ValidatorSetSigCallerSession) WARPMESSENGER() (common.Address, error) { + return _ValidatorSetSig.Contract.WARPMESSENGER(&_ValidatorSetSig.CallOpts) +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_ValidatorSetSig *ValidatorSetSigCaller) BlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ValidatorSetSig.contract.Call(opts, &out, "blockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_ValidatorSetSig *ValidatorSetSigSession) BlockchainID() ([32]byte, error) { + return _ValidatorSetSig.Contract.BlockchainID(&_ValidatorSetSig.CallOpts) +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_ValidatorSetSig *ValidatorSetSigCallerSession) BlockchainID() ([32]byte, error) { + return _ValidatorSetSig.Contract.BlockchainID(&_ValidatorSetSig.CallOpts) +} + +// Nonces is a free data retrieval call binding the contract method 0x7ecebe00. +// +// Solidity: function nonces(address targetContractAddress) view returns(uint256 nonce) +func (_ValidatorSetSig *ValidatorSetSigCaller) Nonces(opts *bind.CallOpts, targetContractAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _ValidatorSetSig.contract.Call(opts, &out, "nonces", targetContractAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Nonces is a free data retrieval call binding the contract method 0x7ecebe00. +// +// Solidity: function nonces(address targetContractAddress) view returns(uint256 nonce) +func (_ValidatorSetSig *ValidatorSetSigSession) Nonces(targetContractAddress common.Address) (*big.Int, error) { + return _ValidatorSetSig.Contract.Nonces(&_ValidatorSetSig.CallOpts, targetContractAddress) +} + +// Nonces is a free data retrieval call binding the contract method 0x7ecebe00. +// +// Solidity: function nonces(address targetContractAddress) view returns(uint256 nonce) +func (_ValidatorSetSig *ValidatorSetSigCallerSession) Nonces(targetContractAddress common.Address) (*big.Int, error) { + return _ValidatorSetSig.Contract.Nonces(&_ValidatorSetSig.CallOpts, targetContractAddress) +} + +// ValidateMessage is a free data retrieval call binding the contract method 0x7d969c34. +// +// Solidity: function validateMessage((bytes32,address,address,uint256,uint256,bytes) message) view returns() +func (_ValidatorSetSig *ValidatorSetSigCaller) ValidateMessage(opts *bind.CallOpts, message ValidatorSetSigMessage) error { + var out []interface{} + err := _ValidatorSetSig.contract.Call(opts, &out, "validateMessage", message) + + if err != nil { + return err + } + + return err + +} + +// ValidateMessage is a free data retrieval call binding the contract method 0x7d969c34. +// +// Solidity: function validateMessage((bytes32,address,address,uint256,uint256,bytes) message) view returns() +func (_ValidatorSetSig *ValidatorSetSigSession) ValidateMessage(message ValidatorSetSigMessage) error { + return _ValidatorSetSig.Contract.ValidateMessage(&_ValidatorSetSig.CallOpts, message) +} + +// ValidateMessage is a free data retrieval call binding the contract method 0x7d969c34. +// +// Solidity: function validateMessage((bytes32,address,address,uint256,uint256,bytes) message) view returns() +func (_ValidatorSetSig *ValidatorSetSigCallerSession) ValidateMessage(message ValidatorSetSigMessage) error { + return _ValidatorSetSig.Contract.ValidateMessage(&_ValidatorSetSig.CallOpts, message) +} + +// ValidatorBlockchainID is a free data retrieval call binding the contract method 0x8d6e579d. +// +// Solidity: function validatorBlockchainID() view returns(bytes32) +func (_ValidatorSetSig *ValidatorSetSigCaller) ValidatorBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ValidatorSetSig.contract.Call(opts, &out, "validatorBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ValidatorBlockchainID is a free data retrieval call binding the contract method 0x8d6e579d. +// +// Solidity: function validatorBlockchainID() view returns(bytes32) +func (_ValidatorSetSig *ValidatorSetSigSession) ValidatorBlockchainID() ([32]byte, error) { + return _ValidatorSetSig.Contract.ValidatorBlockchainID(&_ValidatorSetSig.CallOpts) +} + +// ValidatorBlockchainID is a free data retrieval call binding the contract method 0x8d6e579d. +// +// Solidity: function validatorBlockchainID() view returns(bytes32) +func (_ValidatorSetSig *ValidatorSetSigCallerSession) ValidatorBlockchainID() ([32]byte, error) { + return _ValidatorSetSig.Contract.ValidatorBlockchainID(&_ValidatorSetSig.CallOpts) +} + +// ExecuteCall is a paid mutator transaction binding the contract method 0x5433da42. +// +// Solidity: function executeCall(uint32 messageIndex) payable returns() +func (_ValidatorSetSig *ValidatorSetSigTransactor) ExecuteCall(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ValidatorSetSig.contract.Transact(opts, "executeCall", messageIndex) +} + +// ExecuteCall is a paid mutator transaction binding the contract method 0x5433da42. +// +// Solidity: function executeCall(uint32 messageIndex) payable returns() +func (_ValidatorSetSig *ValidatorSetSigSession) ExecuteCall(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorSetSig.Contract.ExecuteCall(&_ValidatorSetSig.TransactOpts, messageIndex) +} + +// ExecuteCall is a paid mutator transaction binding the contract method 0x5433da42. +// +// Solidity: function executeCall(uint32 messageIndex) payable returns() +func (_ValidatorSetSig *ValidatorSetSigTransactorSession) ExecuteCall(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorSetSig.Contract.ExecuteCall(&_ValidatorSetSig.TransactOpts, messageIndex) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_ValidatorSetSig *ValidatorSetSigTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorSetSig.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_ValidatorSetSig *ValidatorSetSigSession) Receive() (*types.Transaction, error) { + return _ValidatorSetSig.Contract.Receive(&_ValidatorSetSig.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_ValidatorSetSig *ValidatorSetSigTransactorSession) Receive() (*types.Transaction, error) { + return _ValidatorSetSig.Contract.Receive(&_ValidatorSetSig.TransactOpts) +} + +// ValidatorSetSigDeliveredIterator is returned from FilterDelivered and is used to iterate over the raw logs and unpacked data for Delivered events raised by the ValidatorSetSig contract. +type ValidatorSetSigDeliveredIterator struct { + Event *ValidatorSetSigDelivered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorSetSigDeliveredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorSetSigDelivered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorSetSigDelivered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorSetSigDeliveredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorSetSigDeliveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorSetSigDelivered represents a Delivered event raised by the ValidatorSetSig contract. +type ValidatorSetSigDelivered struct { + TargetContractAddress common.Address + Nonce *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelivered is a free log retrieval operation binding the contract event 0x5942a9a3968c7d49fc51c027041544ea295f5c1e395d6d8aa35c4369959f8ed9. +// +// Solidity: event Delivered(address indexed targetContractAddress, uint256 indexed nonce) +func (_ValidatorSetSig *ValidatorSetSigFilterer) FilterDelivered(opts *bind.FilterOpts, targetContractAddress []common.Address, nonce []*big.Int) (*ValidatorSetSigDeliveredIterator, error) { + + var targetContractAddressRule []interface{} + for _, targetContractAddressItem := range targetContractAddress { + targetContractAddressRule = append(targetContractAddressRule, targetContractAddressItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _ValidatorSetSig.contract.FilterLogs(opts, "Delivered", targetContractAddressRule, nonceRule) + if err != nil { + return nil, err + } + return &ValidatorSetSigDeliveredIterator{contract: _ValidatorSetSig.contract, event: "Delivered", logs: logs, sub: sub}, nil +} + +// WatchDelivered is a free log subscription operation binding the contract event 0x5942a9a3968c7d49fc51c027041544ea295f5c1e395d6d8aa35c4369959f8ed9. +// +// Solidity: event Delivered(address indexed targetContractAddress, uint256 indexed nonce) +func (_ValidatorSetSig *ValidatorSetSigFilterer) WatchDelivered(opts *bind.WatchOpts, sink chan<- *ValidatorSetSigDelivered, targetContractAddress []common.Address, nonce []*big.Int) (event.Subscription, error) { + + var targetContractAddressRule []interface{} + for _, targetContractAddressItem := range targetContractAddress { + targetContractAddressRule = append(targetContractAddressRule, targetContractAddressItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _ValidatorSetSig.contract.WatchLogs(opts, "Delivered", targetContractAddressRule, nonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorSetSigDelivered) + if err := _ValidatorSetSig.contract.UnpackLog(event, "Delivered", 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 +} + +// ParseDelivered is a log parse operation binding the contract event 0x5942a9a3968c7d49fc51c027041544ea295f5c1e395d6d8aa35c4369959f8ed9. +// +// Solidity: event Delivered(address indexed targetContractAddress, uint256 indexed nonce) +func (_ValidatorSetSig *ValidatorSetSigFilterer) ParseDelivered(log types.Log) (*ValidatorSetSigDelivered, error) { + event := new(ValidatorSetSigDelivered) + if err := _ValidatorSetSig.contract.UnpackLog(event, "Delivered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/governance/ValidatorSetSig/packing.go b/abi-bindings/go/governance/ValidatorSetSig/packing.go new file mode 100644 index 000000000..60ee1b08c --- /dev/null +++ b/abi-bindings/go/governance/ValidatorSetSig/packing.go @@ -0,0 +1,64 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package validatorsetsig + +import ( + "fmt" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/pkg/errors" +) + +var validatorSetSigMessageType abi.Type + +func init() { + // Create an ABI binding for ValidatorSetSigMessage, defined in ValidatorSetSig.sol + // abigen does not support ABI bindings for standalone structs, only methods and events, + // so we must manually keep this up-to-date with the struct defined in the contract. + var err error + validatorSetSigMessageType, err = abi.NewType("tuple", "struct Overloader.F", []abi.ArgumentMarshaling{ + {Name: "targetBlockchainID", Type: "bytes32"}, + {Name: "validatorSetSigAddress", Type: "address"}, + {Name: "targetContractAddress", Type: "address"}, + {Name: "nonce", Type: "uint256"}, + {Name: "value", Type: "uint256"}, + {Name: "payload", Type: "bytes"}, + }) + if err != nil { + panic(fmt.Sprintf("failed to create ValidatorSetSigMessage ABI type: %v", err)) + } +} + +func (m *ValidatorSetSigMessage) Pack() ([]byte, error) { + args := abi.Arguments{ + { + Name: "validatorSetSigMessage", + Type: validatorSetSigMessageType, + }, + } + return args.Pack(m) +} + +func (m *ValidatorSetSigMessage) Unpack(messageBytes []byte) error { + args := abi.Arguments{ + { + Name: "validatorSetSigMessage", + Type: validatorSetSigMessageType, + }, + } + unpacked, err := args.Unpack(messageBytes) + if err != nil { + return fmt.Errorf("failed to unpack to ValidatorSetSigMessage with err: %v", err) + } + return args.Copy(&m, unpacked) +} + +// PackExecuteCall packs the input to form a call to the executeCall function +func PackExecuteCall(messageIndex uint32) ([]byte, error) { + abi, err := ValidatorSetSigMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + return abi.Pack("executeCall", messageIndex) +} diff --git a/abi-bindings/go/ictt/TokenHome/ERC20TokenHome/ERC20TokenHome.go b/abi-bindings/go/ictt/TokenHome/ERC20TokenHome/ERC20TokenHome.go new file mode 100644 index 000000000..d796cb9d6 --- /dev/null +++ b/abi-bindings/go/ictt/TokenHome/ERC20TokenHome/ERC20TokenHome.go @@ -0,0 +1,2833 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokenhome + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RemoteTokenTransferrerSettings is an auto generated low-level Go binding around an user-defined struct. +type RemoteTokenTransferrerSettings struct { + Registered bool + CollateralNeeded *big.Int + TokenMultiplier *big.Int + MultiplyOnRemote bool +} + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// ERC20TokenHomeMetaData contains all meta data concerning the ERC20TokenHome contract. +var ERC20TokenHomeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"CollateralAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialCollateralNeeded\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"RemoteRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ERC20_TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getRemoteTokenTransferrerSettings\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralNeeded\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"multiplyOnRemote\",\"type\":\"bool\"}],\"internalType\":\"structRemoteTokenTransferrerSettings\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getTransferredBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161502438038061502483398101604081905261002e91610893565b61003b8585858585610048565b505050505061090d565b50565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f811580156100915750825b90505f826001600160401b031660011480156100ac5750303b155b9050811580156100ba575080155b156100d85760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561010657845460ff60401b1916680100000000000000001785555b6101138a8a8a8a8a610165565b831561015957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050565b61016d61018a565b61017a85858585856101da565b610183826101ff565b5050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff166101d857604051631afcd79f60e31b815260040160405180910390fd5b565b6101e261018a565b6101ed858585610248565b6101f5610268565b6101838282610278565b61020761018a565b7f914a9547f6c3ddce1d5efbd9e687708f0d1d408ce129e8e1a88bce4f40e2950080546001600160a01b0319166001600160a01b0392909216919091179055565b61025061018a565b61025a8382610404565b6102638261042a565b505050565b61027061018a565b6101d861043b565b61028061018a565b6001600160a01b0382166102db5760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f20746f6b656e206164647265737300000060448201526064015b60405180910390fd5b60128160ff16111561033a5760405162461bcd60e51b815260206004820152602260248201527f546f6b656e486f6d653a20746f6b656e20646563696d616c7320746f6f2068696044820152610ced60f31b60648201526084016102d2565b5f7f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e60090507302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103d291906108f6565b8155600101805460ff909216600160a01b026001600160a81b03199092166001600160a01b0390931692909217179055565b61040c61018a565b610414610465565b61041c610475565b610426828261047d565b5050565b61043261018a565b61004581610607565b5f7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c75005b6001905550565b61046d61018a565b6101d8610641565b6101d861018a565b61048561018a565b6001600160a01b0382166105015760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084016102d2565b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610566573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061058a91906108f6565b116105df5760405162461bcd60e51b815260206004820152603260248201525f80516020615004833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016102d2565b81546001600160a01b0319166001600160a01b03821617825561060183610670565b50505050565b61060f61018a565b6001600160a01b03811661063857604051631e4fbdf760e01b81525f60048201526024016102d2565b61004581610808565b61064961018a565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0061045e565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa1580156106d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106fb91906108f6565b60028301549091508184111561075a5760405162461bcd60e51b815260206004820152603160248201525f8051602061500483398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016102d2565b8084116107cf5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016102d2565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b80516001600160a01b038116811461088e575f80fd5b919050565b5f805f805f60a086880312156108a7575f80fd5b6108b086610878565b94506108be60208701610878565b9350604086015192506108d360608701610878565b9150608086015160ff811681146108e8575f80fd5b809150509295509295909350565b5f60208284031215610906575f80fd5b5051919050565b6146ea8061091a5f395ff3fe608060405234801561000f575f80fd5b5060043610610127575f3560e01c806365690038116100a9578063c8511ada1161006e578063c8511ada146102b4578063c868efaa14610388578063d2cc7a701461039b578063f2fde38b146103c2578063fd658268146103d5575f80fd5b80636569003814610232578063715018a6146102455780638da5cb5b1461024d578063909a6ac01461027d5780639731429714610291575f80fd5b80634511243e116100ef5780634511243e146101d15780634797735f146101e45780635d16225d146101f85780635eb995141461020b57806362e3901b1461021e575f80fd5b806310fe9ae81461012b578063154d625a146101745780632b0d8f18146101955780633bb03890146101aa5780634213cf78146101bd575b5f80fd5b7f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e601546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b61018761018236600461368c565b6103e8565b60405190815260200161016b565b6101a86101a33660046136ba565b610430565b005b6101a86101b83660046136e3565b610532565b5f8051602061461583398151915254610187565b6101a86101df3660046136ba565b610646565b6101875f8051602061467583398151915281565b6101a8610206366004613747565b610735565b6101a8610219366004613776565b610751565b6101875f8051602061461583398151915281565b6101a861024036600461378d565b610765565b6101a861078e565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610157565b6101875f8051602061469583398151915281565b6102a461029f3660046136ba565b6107a1565b604051901515815260200161016b565b6103516102c236600461368c565b60408051608080820183525f808352602080840182905283850182905260609384018290529581525f8051602061463583398151915286528381206001600160a01b039590951681529385529282902082519384018352805460ff9081161515855260018201549585019590955260028101549284019290925260039091015490921615159181019190915290565b60405161016b9190815115158152602080830151908201526040808301519082015260609182015115159181019190915260800190565b6101a86103963660046137d3565b6107c1565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0254610187565b6101a86103d03660046136ba565b61097e565b6101a86103e3366004613854565b6109b8565b5f8281527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03851684529091529020545b92915050565b5f805160206146958339815191526104466109c8565b6001600160a01b0382166104755760405162461bcd60e51b815260040161046c90613889565b60405180910390fd5b61047f81836109d0565b156104e25760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b606482015260840161046c565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156105765750825b90505f826001600160401b031660011480156105915750303b155b90508115801561059f575080155b156105bd5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156105e757845460ff60401b1916600160401b1785555b6105f48a8a8a8a8a6109f1565b831561063a57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050565b5f8051602061469583398151915261065c6109c8565b6001600160a01b0382166106825760405162461bcd60e51b815260040161046c90613889565b61068c81836109d0565b6106ea5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b606482015260840161046c565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b61074d61074736849003840184613989565b82610a16565b5050565b6107596109c8565b61076281610c27565b50565b61074d61077d5f805160206146158339815191525490565b303361078886613a8b565b85610dbf565b610796610fcb565b61079f5f611026565b565b5f5f805160206146958339815191526107ba81846109d0565b9392505050565b6107c9611096565b5f5f8051602061469583398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610834573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108589190613b59565b10156108bf5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b606482015260840161046c565b6108c981336109d0565b1561092f5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b606482015260840161046c565b61096f858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506110e092505050565b506109786114d3565b50505050565b610986610fcb565b6001600160a01b0381166109af57604051631e4fbdf760e01b81525f600482015260240161046c565b61076281611026565b6109c38383836114fd565b505050565b61079f610fcb565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b6109f96116ed565b610a068585858585611736565b610a0f8261175b565b5050505050565b5f805160206146558339815191528054600114610a455760405162461bcd60e51b815260040161046c90613b70565b60028155610a5283611791565b60e08301516001600160a01b031615610a7d5760405162461bcd60e51b815260040161046c90613bb4565b5f80610a9b855f01518660200151868860600151896080015161183a565b915091505f604051806040016040528060016004811115610abe57610abe613bfa565b8152602001604051806040016040528089604001516001600160a01b0316815260200186815250604051602001610af59190613c0e565b60405160208183030381529060405281525090505f610bd46040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b606001516001600160a01b031681526020018781525081526020018960c0015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b604051908082528060200260200182016040528015610ba6578160200160208202803683370190505b50815260200184604051602001610bbd9190613c7b565b6040516020818303038152906040528152506119ff565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb528987604051610c12929190613cbd565b60405180910390a35050600190925550505050565b5f8051602061469583398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f9190613b59565b600283015490915081841115610d115760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b606482015260840161046c565b808411610d865760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e00606482015260840161046c565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b5f805160206146558339815191528054600114610dee5760405162461bcd60e51b815260040161046c90613b70565b60028155610dfb83611b1a565b60c08301516001600160a01b031615610e265760405162461bcd60e51b815260040161046c90613bb4565b5f80610e46855f015186602001518688610100015189610120015161183a565b915091505f604051806040016040528060026004811115610e6957610e69613bfa565b81526020016040518061010001604052808c81526020018b6001600160a01b031681526020018a6001600160a01b0316815260200189604001516001600160a01b03168152602001868152602001896060015181526020018960a0015181526020018960e001516001600160a01b0316815250604051602001610eec9190613d3e565b60405160208183030381529060405281525090505f610f756040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b61010001516001600160a01b03168152602001878152508152602001896080015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b9050876001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168987604051610fb3929190613ddc565b60405180910390a35050600190925550505050505050565b33610ffd7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03161461079f5760405163118cdaa760e01b815233600482015260240161046c565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008054600119016110da57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f5f8051602061461583398151915290505f828060200190518101906111069190613f00565b905060018151600481111561111d5761111d613bfa565b03611165575f816020015180602001905181019061113b9190613f88565b90505f61114d87878460200151611cff565b905061115c825f015182611d8a565b50505050505050565b60028151600481111561117a5761117a613bfa565b03611293575f81602001518060200190518101906111989190613fc0565b90505f6111aa87878460800151611cff565b825190915087146112105760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a206d69736d61746368656420736f7572636520626c6f60448201526918dad8da185a5b88125160b21b606482015260840161046c565b856001600160a01b031682602001516001600160a01b0316146112895760405162461bcd60e51b815260206004820152602b60248201527f546f6b656e486f6d653a206d69736d617463686564206f726967696e2073656e60448201526a646572206164647265737360a81b606482015260840161046c565b61115c8282611ded565b6003815160048111156112a8576112a8613bfa565b0361137c575f81602001518060200190518101906112c6919061408a565b90505f806112de888885606001518660800151611fcd565b91509150611372604051806101000160405280855f0151815260200185602001516001600160a01b0316815260200185604001516001600160a01b03168152602001876001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018381526020015f81526020018560a0015181526020018560c001516001600160a01b031681525083612078565b5050505050505050565b60048151600481111561139157611391613bfa565b0361148c575f81602001518060200190518101906113af9190614123565b90505f806113c888888560800151866101400151611fcd565b915091506113728888855f01516040518061016001604052808860200151815260200188604001516001600160a01b0316815260200188606001516001600160a01b031681526020018860a00151815260200188610100015181526020018860c0015181526020018861012001516001600160a01b031681526020018860e001516001600160a01b031681526020018a6001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018681526020015f81525086612203565b5f815160048111156114a0576114a0613bfa565b03610a0f575f81602001518060200190518101906114be919061421b565b90506114cb8686836123e0565b505050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b5f80516020614655833981519152805460011461152c5760405162461bcd60e51b815260040161046c90613b70565b60028082555f8581525f80516020614635833981519152602090815260408083206001600160a01b03881684528252918290208251608081018452815460ff9081161515808352600184015494830194909452948201549381019390935260030154909216151560608201525f80516020614615833981519152916115c35760405162461bcd60e51b815260040161046c90614281565b5f8160200151116116205760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20636f6c6c61746572616c206e656564656044820152601960fa1b606482015260840161046c565b611629846127e7565b93505f80826020015186106116585760208301515f925061164a90876142ca565b90508260200151955061166b565b85836020015161166891906142ca565b91505b5f88815260028501602090815260408083206001600160a01b038b168085529083529281902060010185905580518981529182018590528a917f6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6910160405180910390a380156116df576116df3382611d8a565b505060019092555050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661079f57604051631afcd79f60e31b815260040160405180910390fd5b61173e6116ed565b61174985858561280e565b611751612829565b610a0f8282612839565b6117636116ed565b5f8051602061467583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b60408101516001600160a01b03166117f55760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20726563697069656e74206164647265736044820152607360f81b606482015260840161046c565b5f8160c00151116118185760405162461bcd60e51b815260040161046c906142dd565b60a0810151156107625760405162461bcd60e51b815260040161046c9061431f565b5f8581525f80516020614635833981519152602090815260408083206001600160a01b038816845282528083208151608081018352815460ff90811615158083526001840154958301959095526002830154938201939093526003909101549091161515606082015282915f8051602061461583398151915291906118d15760405162461bcd60e51b815260040161046c90614281565b6020810151156119335760405162461bcd60e51b815260206004820152602760248201527f546f6b656e486f6d653a20636f6c6c61746572616c206e656564656420666f726044820152662072656d6f746560c81b606482015260840161046c565b61193c876127e7565b965084156119525761194f8633876129a0565b94505b5f611966826040015183606001518a612af9565b90505f81116119b75760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f207363616c656420616d6f756e74000000604482015260640161046c565b5f8a815260038401602090815260408083206001600160a01b038d168452909152812080548392906119ea908490614360565b90915550909a95995094975050505050505050565b5f80611a09612b0f565b60408401516020015190915015611aae576040830151516001600160a01b0316611a8b5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b606482015260840161046c565b604083015160208101519051611aae916001600160a01b03909116908390612bff565b604051630624488560e41b81526001600160a01b03821690636244885090611ada908690600401614373565b6020604051808303815f875af1158015611af6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107ba9190613b59565b60408101516001600160a01b0316611b875760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420636f6e7472616044820152696374206164647265737360b01b606482015260840161046c565b5f816080015111611baa5760405162461bcd60e51b815260040161046c906142dd565b5f8160a0015111611c095760405162461bcd60e51b815260206004820152602360248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420676173206c696044820152621b5a5d60ea1b606482015260840161046c565b80608001518160a0015110611c6f5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420726563697069656e7420676173604482015265081b1a5b5a5d60d21b606482015260840161046c565b60e08101516001600160a01b0316611cdc5760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f2066616c6c6261636b20726563697069656044820152696e74206164647265737360b01b606482015260840161046c565b610140810151156107625760405162461bcd60e51b815260040161046c9061431f565b5f8381525f80516020614635833981519152602090815260408083206001600160a01b038616845282528083208151608081018352815460ff9081161515825260018301549482019490945260028201549281019290925260030154909116151560608201525f8051602061461583398151915290611d8081878787612c86565b9695505050505050565b6040518181525f80516020614675833981519152906001600160a01b038416907f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b9060200160405180910390a280546109c3906001600160a01b03168484612d7d565b5f80516020614675833981519152805460608401516001600160a01b0390911690611e1a90829085612bff565b5f845f01518560200151866040015184878960a00151604051602401611e459695949392919061442a565b60408051601f198184030181529190526020810180516001600160e01b03166394395edd60e01b17905260c086015160608701519192505f91611e89919084612ddc565b6060870151604051636eb1769f60e11b81523060048201526001600160a01b0391821660248201529192505f919085169063dd62ed3e90604401602060405180830381865afa158015611ede573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f029190613b59565b9050611f138488606001515f612de9565b8115611f655786606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff487604051611f5891815260200190565b60405180910390a2611fad565b86606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb087604051611fa491815260200190565b60405180910390a25b801561115c5760e087015161115c906001600160a01b0386169083612d7d565b5f8481525f80516020614635833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff90811615158252600183015494820194909452600282015492810192909252600301549091161515606082015281905f805160206146158339815191529082612051828a8a8a612c86565b90505f6120678360400151846060015189612e78565b919a91995090975050505050505050565b5f8051602061465583398151915280546001146120a75760405162461bcd60e51b815260040161046c90613b70565b600281556120b483611791565b5f6120cc845f01518560200151858760800151612e85565b9050805f036120e9576120e38460e0015184611d8a565b506121fb565b604080518082019091525f908060018152602001604051806040016040528088604001516001600160a01b031681526020018581525060405160200161212f9190613c0e565b60405160208183030381529060405281525090505f6121bb6040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a606001516001600160a01b031681526020018a6080015181525081526020018860c0015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b9050807f825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf087856040516121ef929190613cbd565b60405180910390a25050505b600190555050565b5f8051602061465583398151915280546001146122325760405162461bcd60e51b815260040161046c90613b70565b6002815561223f83611b1a565b5f612258845f0151856020015185876101200151612e85565b9050805f036122755761226f8460c0015184611d8a565b506123d5565b604080518082019091525f9080600281526020016040518061010001604052808b81526020018a6001600160a01b03168152602001896001600160a01b0316815260200188604001516001600160a01b03168152602001858152602001886060015181526020018860a0015181526020018860e001516001600160a01b03168152506040516020016123079190613d3e565b60405160208183030381529060405281525090505f6123956040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a61010001516001600160a01b031681526020018a61012001518152508152602001886080015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b9050807f42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb3087856040516123c9929190613ddc565b60405180910390a25050505b600190555050505050565b5f80516020614615833981519152836124475760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a207a65726f2072656d6f746520626c6f636b636861696044820152631b88125160e21b606482015260840161046c565b805484036124af5760405162461bcd60e51b815260206004820152602f60248201527f546f6b656e486f6d653a2063616e6e6f742072656769737465722072656d6f7460448201526e329037b71039b0b6b29031b430b4b760891b606482015260840161046c565b6001600160a01b03831661251e5760405162461bcd60e51b815260206004820152603060248201527f546f6b656e486f6d653a207a65726f2072656d6f746520746f6b656e2074726160448201526f6e73666572726572206164647265737360801b606482015260840161046c565b5f84815260028201602090815260408083206001600160a01b038716845290915290205460ff161561259e5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f746520616c726561647920726567697374604482015263195c995960e21b606482015260840161046c565b6012826040015160ff1611156126085760405162461bcd60e51b815260206004820152602960248201527f546f6b656e486f6d653a2072656d6f746520746f6b656e20646563696d616c73604482015268040e8dede40d0d2ced60bb1b606482015260840161046c565b6001810154602083015160ff908116600160a01b909204161461267c5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420686f6d6520746f6b656e20646560448201526563696d616c7360d01b606482015260840161046c565b5f8061269d8360010160149054906101000a900460ff168560400151612ff6565b915091505f6126b08383875f0151612e78565b90508180156126ca575084516126c790849061447e565b15155b156126dd576126da600182614360565b90505b6040518060800160405280600115158152602001828152602001848152602001831515815250846002015f8981526020019081526020015f205f886001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003015f6101000a81548160ff021916908315150217905550905050856001600160a01b0316877ff229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b908388604001516040516127d692919091825260ff16602082015260400190565b60405180910390a350505050505050565b5f8051602061467583398151915280545f91906107ba906001600160a01b031633856129a0565b6128166116ed565b612820838261303e565b6109c382613060565b6128316116ed565b61079f613071565b6128416116ed565b6001600160a01b0382166128975760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f20746f6b656e2061646472657373000000604482015260640161046c565b60128160ff1611156128f65760405162461bcd60e51b815260206004820152602260248201527f546f6b656e486f6d653a20746f6b656e20646563696d616c7320746f6f2068696044820152610ced60f31b606482015260840161046c565b5f5f8051602061461583398151915290506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561294a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061296e9190613b59565b8155600101805460ff909216600160a01b026001600160a81b03199092166001600160a01b0390931692909217179055565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa1580156129e6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a0a9190613b59565b9050612a216001600160a01b038616853086613085565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612a65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a899190613b59565b9050818111612aef5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840161046c565b611d8082826142ca565b5f612b0784848460016130be565b949350505050565b5f8051602061469583398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b8d9190614491565b9050612b9982826109d0565b1561042a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b606482015260840161046c565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612c4c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c709190613b59565b90506109788484612c818585614360565b612de9565b83515f90612ca65760405162461bcd60e51b815260040161046c90614281565b602085015115612d045760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f7465206e6f7420636f6c6c61746572616c6044820152631a5e995960e21b606482015260840161046c565b612d0f8484846130e5565b5f612d238660400151876060015185612e78565b90505f8111612d745760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e486f6d653a207a65726f20746f6b656e20616d6f756e7400000000604482015260640161046c565b95945050505050565b6040516001600160a01b038381166024830152604482018390526109c391859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506131d2565b5f612b07845f8585613233565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612e3a8482613303565b610978576040516001600160a01b0384811660248301525f6044830152612e6e91869182169063095ea7b390606401612daa565b61097884826131d2565b5f612b078484845f6130be565b5f8481525f80516020614635833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff9081161580158352600184015495830195909552600283015493820193909352600390910154909116151560608201525f805160206146158339815191529180612f0b57505f8160200151115b15612f1a575f92505050612b07565b838511612f7e5760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e486f6d653a20696e73756666696369656e7420616d6f756e74207460448201526b6f20636f766572206665657360a01b606482015260840161046c565b612f8884866142ca565b94505f612f9e8260400151836060015188612af9565b9050805f03612fb2575f9350505050612b07565b5f88815260038401602090815260408083206001600160a01b038b16845290915281208054839290612fe5908490614360565b909155509098975050505050505050565b5f8060ff8085169084161181816130195761301185876144ac565b60ff16613027565b61302386866144ac565b60ff165b61303290600a6145a5565b96919550909350505050565b6130466116ed565b61304e6133a0565b6130566133b0565b61074d82826133b8565b6130686116ed565b6107628161353c565b5f5f805160206146558339815191526114f6565b6040516001600160a01b0384811660248301528381166044830152606482018390526109789186918216906323b872dd90608401612daa565b5f811515841515036130db576130d485846145b0565b9050612b07565b612d7485846145c7565b5f8381527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03861684529091529020545f80516020614615833981519152908281101561319c5760405162461bcd60e51b815260206004820152602e60248201527f546f6b656e486f6d653a20696e73756666696369656e7420746f6b656e20747260448201526d616e736665722062616c616e636560901b606482015260840161046c565b6131a683826142ca565b5f9586526003909201602090815260408087206001600160a01b03909616875294905250919092205550565b5f6131e66001600160a01b03841683613544565b905080515f1415801561320a57508080602001905181019061320891906145da565b155b156109c357604051635274afe760e01b81526001600160a01b038416600482015260240161046c565b5f845a10156132845760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e74206761730000000000604482015260640161046c565b834710156132d45760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c7565000000604482015260640161046c565b826001600160a01b03163b5f036132ec57505f612b07565b5f805f84516020860188888bf19695505050505050565b5f805f846001600160a01b03168460405161331e91906145f9565b5f604051808303815f865af19150503d805f8114613357576040519150601f19603f3d011682016040523d82523d5f602084013e61335c565b606091505b509150915081801561338657508051158061338657508080602001905181019061338691906145da565b8015612d745750505050506001600160a01b03163b151590565b6133a86116ed565b61079f613551565b61079f6116ed565b6133c06116ed565b6001600160a01b03821661343c5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840161046c565b5f5f8051602061469583398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561348e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134b29190613b59565b1161351a5760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b606482015260840161046c565b81546001600160a01b0319166001600160a01b03821617825561097883610c27565b6109866116ed565b60606107ba83835f613559565b6114d36116ed565b60608147101561357e5760405163cd78605960e01b815230600482015260240161046c565b5f80856001600160a01b0316848660405161359991906145f9565b5f6040518083038185875af1925050503d805f81146135d3576040519150601f19603f3d011682016040523d82523d5f602084013e6135d8565b606091505b5091509150611d808683836060826135f8576135f38261363f565b6107ba565b815115801561360f57506001600160a01b0384163b155b1561363857604051639996b31560e01b81526001600160a01b038516600482015260240161046c565b50806107ba565b80511561364f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610762575f80fd5b803561368781613668565b919050565b5f806040838503121561369d575f80fd5b8235915060208301356136af81613668565b809150509250929050565b5f602082840312156136ca575f80fd5b81356107ba81613668565b60ff81168114610762575f80fd5b5f805f805f60a086880312156136f7575f80fd5b853561370281613668565b9450602086013561371281613668565b935060408601359250606086013561372981613668565b91506080860135613739816136d5565b809150509295509295909350565b5f8082840361012081121561375a575f80fd5b61010080821215613769575f80fd5b9395938601359450505050565b5f60208284031215613786575f80fd5b5035919050565b5f806040838503121561379e575f80fd5b82356001600160401b038111156137b3575f80fd5b830161016081860312156137c5575f80fd5b946020939093013593505050565b5f805f80606085870312156137e6575f80fd5b8435935060208501356137f881613668565b925060408501356001600160401b0380821115613813575f80fd5b818701915087601f830112613826575f80fd5b813581811115613834575f80fd5b886020828501011115613845575f80fd5b95989497505060200194505050565b5f805f60608486031215613866575f80fd5b83359250602084013561387881613668565b929592945050506040919091013590565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b60405161010081016001600160401b038111828210171561390e5761390e6138d7565b60405290565b60405161016081016001600160401b038111828210171561390e5761390e6138d7565b604080519081016001600160401b038111828210171561390e5761390e6138d7565b604051601f8201601f191681016001600160401b0381118282101715613981576139816138d7565b604052919050565b5f610100828403121561399a575f80fd5b6139a26138eb565b8235815260208301356139b481613668565b602082015260408301356139c781613668565b60408201526139d86060840161367c565b60608201526080830135608082015260a083013560a082015260c083013560c0820152613a0760e0840161367c565b60e08201529392505050565b5f6001600160401b03821115613a2b57613a2b6138d7565b50601f01601f191660200190565b5f82601f830112613a48575f80fd5b8135613a5b613a5682613a13565b613959565b818152846020838601011115613a6f575f80fd5b816020850160208301375f918101602001919091529392505050565b5f6101608236031215613a9c575f80fd5b613aa4613914565b82358152613ab46020840161367c565b6020820152613ac56040840161367c565b604082015260608301356001600160401b03811115613ae2575f80fd5b613aee36828601613a39565b6060830152506080830135608082015260a083013560a0820152613b1460c0840161367c565b60c0820152613b2560e0840161367c565b60e0820152610100613b3881850161367c565b90820152610120838101359082015261014092830135928101929092525090565b5f60208284031215613b69575f80fd5b5051919050565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b60208082526026908201527f546f6b656e486f6d653a206e6f6e2d7a65726f206d756c74692d686f702066616040820152656c6c6261636b60d01b606082015260800190565b634e487b7160e01b5f52602160045260245ffd5b81516001600160a01b03168152602080830151908201526040810161042a565b5f5b83811015613c48578181015183820152602001613c30565b50505f910152565b5f8151808452613c67816020860160208601613c2e565b601f01601f19169290920160200192915050565b602081525f825160058110613c9e57634e487b7160e01b5f52602160045260245ffd5b806020840152506020830151604080840152612b076060840182613c50565b5f6101208201905083518252602084015160018060a01b03808216602085015280604087015116604085015280606087015116606085015250506080840151608083015260a084015160a083015260c084015160c083015260e0840151613d2f60e08401826001600160a01b03169052565b50826101008301529392505050565b60208152815160208201525f602083015160018060a01b03808216604085015280604086015116606085015250506060830151613d8660808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c0850152613dad610120850183613c50565b915060c085015160e085015260e0850151613dd2828601826001600160a01b03169052565b5090949350505050565b60408152825160408201525f6020840151613e0260608401826001600160a01b03169052565b5060408401516001600160a01b03166080830152606084015161016060a08401819052613e336101a0850183613c50565b9150608086015160c085015260a086015160e085015260c0860151610100613e65818701836001600160a01b03169052565b60e08801519150610120613e83818801846001600160a01b03169052565b90880151915061014090613ea1878301846001600160a01b03169052565b880151928601929092525090940151610180830152506020015290565b5f82601f830112613ecd575f80fd5b8151613edb613a5682613a13565b818152846020838601011115613eef575f80fd5b612b07826020830160208701613c2e565b5f60208284031215613f10575f80fd5b81516001600160401b0380821115613f26575f80fd5b9083019060408286031215613f39575f80fd5b613f41613937565b825160058110613f4f575f80fd5b8152602083015182811115613f62575f80fd5b613f6e87828601613ebe565b60208301525095945050505050565b805161368781613668565b5f60408284031215613f98575f80fd5b613fa0613937565b8251613fab81613668565b81526020928301519281019290925250919050565b5f60208284031215613fd0575f80fd5b81516001600160401b0380821115613fe6575f80fd5b908301906101008286031215613ffa575f80fd5b6140026138eb565b8251815261401260208401613f7d565b602082015261402360408401613f7d565b604082015261403460608401613f7d565b60608201526080830151608082015260a083015182811115614054575f80fd5b61406087828601613ebe565b60a08301525060c083015160c082015261407c60e08401613f7d565b60e082015295945050505050565b5f60e0828403121561409a575f80fd5b60405160e081018181106001600160401b03821117156140bc576140bc6138d7565b6040528251815260208301516140d181613668565b602082015260408301516140e481613668565b80604083015250606083015160608201526080830151608082015260a083015160a082015260c083015161411781613668565b60c08201529392505050565b5f60208284031215614133575f80fd5b81516001600160401b0380821115614149575f80fd5b90830190610160828603121561415d575f80fd5b614165613914565b61416e83613f7d565b81526020830151602082015261418660408401613f7d565b604082015261419760608401613f7d565b60608201526080830151608082015260a0830151828111156141b7575f80fd5b6141c387828601613ebe565b60a08301525060c083015160c08201526141df60e08401613f7d565b60e0820152610100838101519082015261012091506141ff828401613f7d565b9181019190915261014091820151918101919091529392505050565b5f6060828403121561422b575f80fd5b604051606081018181106001600160401b038211171561424d5761424d6138d7565b604052825181526020830151614262816136d5565b60208201526040830151614275816136d5565b60408201529392505050565b6020808252818101527f546f6b656e486f6d653a2072656d6f7465206e6f742072656769737465726564604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561042a5761042a6142b6565b60208082526022908201527f546f6b656e486f6d653a207a65726f20726571756972656420676173206c696d6040820152611a5d60f21b606082015260800190565b60208082526021908201527f546f6b656e486f6d653a206e6f6e2d7a65726f207365636f6e646172792066656040820152606560f81b606082015260800190565b8082018082111561042a5761042a6142b6565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b80841015614400578451831682529385019360019390930192908501906143de565b5060a0880151878203601f190160e0890152945061441e8186613c50565b98975050505050505050565b8681526001600160a01b0386811660208301528581166040830152841660608201526080810183905260c060a082018190525f9061441e90830184613c50565b634e487b7160e01b5f52601260045260245ffd5b5f8261448c5761448c61446a565b500690565b5f602082840312156144a1575f80fd5b81516107ba81613668565b60ff828116828216039081111561042a5761042a6142b6565b600181815b808511156144ff57815f19048211156144e5576144e56142b6565b808516156144f257918102915b93841c93908002906144ca565b509250929050565b5f826145155750600161042a565b8161452157505f61042a565b816001811461453757600281146145415761455d565b600191505061042a565b60ff841115614552576145526142b6565b50506001821b61042a565b5060208310610133831016604e8410600b8410161715614580575081810a61042a565b61458a83836144c5565b805f190482111561459d5761459d6142b6565b029392505050565b5f6107ba8383614507565b808202811582820484141761042a5761042a6142b6565b5f826145d5576145d561446a565b500490565b5f602082840312156145ea575f80fd5b815180151581146107ba575f80fd5b5f825161460a818460208701613c2e565b919091019291505056fe9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e6009316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e602d2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500914a9547f6c3ddce1d5efbd9e687708f0d1d408ce129e8e1a88bce4f40e29500de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a2646970667358221220bf2b91731d0d2bb17e9d85778f2c299d17399553bcb3081f62af5af37b0f921964736f6c6343000819003354656c65706f7274657252656769737472794170703a20696e76616c69642054", +} + +// ERC20TokenHomeABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenHomeMetaData.ABI instead. +var ERC20TokenHomeABI = ERC20TokenHomeMetaData.ABI + +// ERC20TokenHomeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenHomeMetaData.Bin instead. +var ERC20TokenHomeBin = ERC20TokenHomeMetaData.Bin + +// DeployERC20TokenHome deploys a new Ethereum contract, binding an instance of ERC20TokenHome to it. +func DeployERC20TokenHome(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, tokenAddress common.Address, tokenDecimals uint8) (common.Address, *types.Transaction, *ERC20TokenHome, error) { + parsed, err := ERC20TokenHomeMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20TokenHomeBin), backend, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, tokenAddress, tokenDecimals) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenHome{ERC20TokenHomeCaller: ERC20TokenHomeCaller{contract: contract}, ERC20TokenHomeTransactor: ERC20TokenHomeTransactor{contract: contract}, ERC20TokenHomeFilterer: ERC20TokenHomeFilterer{contract: contract}}, nil +} + +// ERC20TokenHome is an auto generated Go binding around an Ethereum contract. +type ERC20TokenHome struct { + ERC20TokenHomeCaller // Read-only binding to the contract + ERC20TokenHomeTransactor // Write-only binding to the contract + ERC20TokenHomeFilterer // Log filterer for contract events +} + +// ERC20TokenHomeCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenHomeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenHomeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenHomeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenHomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenHomeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenHomeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenHomeSession struct { + Contract *ERC20TokenHome // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenHomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenHomeCallerSession struct { + Contract *ERC20TokenHomeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenHomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenHomeTransactorSession struct { + Contract *ERC20TokenHomeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenHomeRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenHomeRaw struct { + Contract *ERC20TokenHome // Generic contract binding to access the raw methods on +} + +// ERC20TokenHomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenHomeCallerRaw struct { + Contract *ERC20TokenHomeCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenHomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenHomeTransactorRaw struct { + Contract *ERC20TokenHomeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenHome creates a new instance of ERC20TokenHome, bound to a specific deployed contract. +func NewERC20TokenHome(address common.Address, backend bind.ContractBackend) (*ERC20TokenHome, error) { + contract, err := bindERC20TokenHome(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenHome{ERC20TokenHomeCaller: ERC20TokenHomeCaller{contract: contract}, ERC20TokenHomeTransactor: ERC20TokenHomeTransactor{contract: contract}, ERC20TokenHomeFilterer: ERC20TokenHomeFilterer{contract: contract}}, nil +} + +// NewERC20TokenHomeCaller creates a new read-only instance of ERC20TokenHome, bound to a specific deployed contract. +func NewERC20TokenHomeCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenHomeCaller, error) { + contract, err := bindERC20TokenHome(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenHomeCaller{contract: contract}, nil +} + +// NewERC20TokenHomeTransactor creates a new write-only instance of ERC20TokenHome, bound to a specific deployed contract. +func NewERC20TokenHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenHomeTransactor, error) { + contract, err := bindERC20TokenHome(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTransactor{contract: contract}, nil +} + +// NewERC20TokenHomeFilterer creates a new log filterer instance of ERC20TokenHome, bound to a specific deployed contract. +func NewERC20TokenHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenHomeFilterer, error) { + contract, err := bindERC20TokenHome(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenHomeFilterer{contract: contract}, nil +} + +// bindERC20TokenHome binds a generic wrapper to an already deployed contract. +func bindERC20TokenHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenHomeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenHome *ERC20TokenHomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenHome.Contract.ERC20TokenHomeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenHome *ERC20TokenHomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.ERC20TokenHomeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenHome *ERC20TokenHomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.ERC20TokenHomeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenHome *ERC20TokenHomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenHome.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenHome *ERC20TokenHomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenHome *ERC20TokenHomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.contract.Transact(opts, method, params...) +} + +// ERC20TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x4797735f. +// +// Solidity: function ERC20_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCaller) ERC20TOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "ERC20_TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ERC20TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x4797735f. +// +// Solidity: function ERC20_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeSession) ERC20TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHome.Contract.ERC20TOKENHOMESTORAGELOCATION(&_ERC20TokenHome.CallOpts) +} + +// ERC20TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x4797735f. +// +// Solidity: function ERC20_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) ERC20TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHome.Contract.ERC20TOKENHOMESTORAGELOCATION(&_ERC20TokenHome.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHome.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenHome.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHome.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenHome.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCaller) TOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHome.Contract.TOKENHOMESTORAGELOCATION(&_ERC20TokenHome.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHome.Contract.TOKENHOMESTORAGELOCATION(&_ERC20TokenHome.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenHome.Contract.GetBlockchainID(&_ERC20TokenHome.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenHome.Contract.GetBlockchainID(&_ERC20TokenHome.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenHome *ERC20TokenHomeCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenHome *ERC20TokenHomeSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenHome.Contract.GetMinTeleporterVersion(&_ERC20TokenHome.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenHome.Contract.GetMinTeleporterVersion(&_ERC20TokenHome.CallOpts) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_ERC20TokenHome *ERC20TokenHomeCaller) GetRemoteTokenTransferrerSettings(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "getRemoteTokenTransferrerSettings", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(RemoteTokenTransferrerSettings), err + } + + out0 := *abi.ConvertType(out[0], new(RemoteTokenTransferrerSettings)).(*RemoteTokenTransferrerSettings) + + return out0, err + +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_ERC20TokenHome *ERC20TokenHomeSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _ERC20TokenHome.Contract.GetRemoteTokenTransferrerSettings(&_ERC20TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _ERC20TokenHome.Contract.GetRemoteTokenTransferrerSettings(&_ERC20TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_ERC20TokenHome *ERC20TokenHomeCaller) GetTokenAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "getTokenAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_ERC20TokenHome *ERC20TokenHomeSession) GetTokenAddress() (common.Address, error) { + return _ERC20TokenHome.Contract.GetTokenAddress(&_ERC20TokenHome.CallOpts) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) GetTokenAddress() (common.Address, error) { + return _ERC20TokenHome.Contract.GetTokenAddress(&_ERC20TokenHome.CallOpts) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_ERC20TokenHome *ERC20TokenHomeCaller) GetTransferredBalance(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "getTransferredBalance", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_ERC20TokenHome *ERC20TokenHomeSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _ERC20TokenHome.Contract.GetTransferredBalance(&_ERC20TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _ERC20TokenHome.Contract.GetTransferredBalance(&_ERC20TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenHome *ERC20TokenHomeCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenHome *ERC20TokenHomeSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenHome.Contract.IsTeleporterAddressPaused(&_ERC20TokenHome.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenHome.Contract.IsTeleporterAddressPaused(&_ERC20TokenHome.CallOpts, teleporterAddress) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenHome *ERC20TokenHomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenHome.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenHome *ERC20TokenHomeSession) Owner() (common.Address, error) { + return _ERC20TokenHome.Contract.Owner(&_ERC20TokenHome.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenHome *ERC20TokenHomeCallerSession) Owner() (common.Address, error) { + return _ERC20TokenHome.Contract.Owner(&_ERC20TokenHome.CallOpts) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xfd658268. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) AddCollateral(opts *bind.TransactOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "addCollateral", remoteBlockchainID, remoteTokenTransferrerAddress, amount) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xfd658268. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.AddCollateral(&_ERC20TokenHome.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress, amount) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xfd658268. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.AddCollateral(&_ERC20TokenHome.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress, amount) +} + +// Initialize is a paid mutator transaction binding the contract method 0x3bb03890. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address tokenAddress, uint8 tokenDecimals) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) Initialize(opts *bind.TransactOpts, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, tokenAddress common.Address, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "initialize", teleporterRegistryAddress, teleporterManager, minTeleporterVersion, tokenAddress, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0x3bb03890. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address tokenAddress, uint8 tokenDecimals) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, tokenAddress common.Address, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.Initialize(&_ERC20TokenHome.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, tokenAddress, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0x3bb03890. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address tokenAddress, uint8 tokenDecimals) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, tokenAddress common.Address, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.Initialize(&_ERC20TokenHome.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, tokenAddress, tokenDecimals) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.PauseTeleporterAddress(&_ERC20TokenHome.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.PauseTeleporterAddress(&_ERC20TokenHome.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.ReceiveTeleporterMessage(&_ERC20TokenHome.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.ReceiveTeleporterMessage(&_ERC20TokenHome.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenHome.Contract.RenounceOwnership(&_ERC20TokenHome.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenHome.Contract.RenounceOwnership(&_ERC20TokenHome.TransactOpts) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) Send(opts *bind.TransactOpts, input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "send", input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.Send(&_ERC20TokenHome.TransactOpts, input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.Send(&_ERC20TokenHome.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "sendAndCall", input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.SendAndCall(&_ERC20TokenHome.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.SendAndCall(&_ERC20TokenHome.TransactOpts, input, amount) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.TransferOwnership(&_ERC20TokenHome.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.TransferOwnership(&_ERC20TokenHome.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.UnpauseTeleporterAddress(&_ERC20TokenHome.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.UnpauseTeleporterAddress(&_ERC20TokenHome.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenHome *ERC20TokenHomeSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.UpdateMinTeleporterVersion(&_ERC20TokenHome.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenHome *ERC20TokenHomeTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenHome.Contract.UpdateMinTeleporterVersion(&_ERC20TokenHome.TransactOpts, version) +} + +// ERC20TokenHomeCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the ERC20TokenHome contract. +type ERC20TokenHomeCallFailedIterator struct { + Event *ERC20TokenHomeCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeCallFailed represents a CallFailed event raised by the ERC20TokenHome contract. +type ERC20TokenHomeCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenHomeCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeCallFailedIterator{contract: _ERC20TokenHome.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeCallFailed) + if err := _ERC20TokenHome.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseCallFailed(log types.Log) (*ERC20TokenHomeCallFailed, error) { + event := new(ERC20TokenHomeCallFailed) + if err := _ERC20TokenHome.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the ERC20TokenHome contract. +type ERC20TokenHomeCallSucceededIterator struct { + Event *ERC20TokenHomeCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeCallSucceeded represents a CallSucceeded event raised by the ERC20TokenHome contract. +type ERC20TokenHomeCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenHomeCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeCallSucceededIterator{contract: _ERC20TokenHome.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeCallSucceeded) + if err := _ERC20TokenHome.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseCallSucceeded(log types.Log) (*ERC20TokenHomeCallSucceeded, error) { + event := new(ERC20TokenHomeCallSucceeded) + if err := _ERC20TokenHome.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeCollateralAddedIterator is returned from FilterCollateralAdded and is used to iterate over the raw logs and unpacked data for CollateralAdded events raised by the ERC20TokenHome contract. +type ERC20TokenHomeCollateralAddedIterator struct { + Event *ERC20TokenHomeCollateralAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeCollateralAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeCollateralAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeCollateralAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeCollateralAdded represents a CollateralAdded event raised by the ERC20TokenHome contract. +type ERC20TokenHomeCollateralAdded struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + Amount *big.Int + Remaining *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollateralAdded is a free log retrieval operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterCollateralAdded(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*ERC20TokenHomeCollateralAddedIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeCollateralAddedIterator{contract: _ERC20TokenHome.contract, event: "CollateralAdded", logs: logs, sub: sub}, nil +} + +// WatchCollateralAdded is a free log subscription operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchCollateralAdded(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeCollateralAdded, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeCollateralAdded) + if err := _ERC20TokenHome.contract.UnpackLog(event, "CollateralAdded", 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 +} + +// ParseCollateralAdded is a log parse operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseCollateralAdded(log types.Log) (*ERC20TokenHomeCollateralAdded, error) { + event := new(ERC20TokenHomeCollateralAdded) + if err := _ERC20TokenHome.contract.UnpackLog(event, "CollateralAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ERC20TokenHome contract. +type ERC20TokenHomeInitializedIterator struct { + Event *ERC20TokenHomeInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeInitialized represents a Initialized event raised by the ERC20TokenHome contract. +type ERC20TokenHomeInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*ERC20TokenHomeInitializedIterator, error) { + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ERC20TokenHomeInitializedIterator{contract: _ERC20TokenHome.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeInitialized) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeInitialized) + if err := _ERC20TokenHome.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseInitialized(log types.Log) (*ERC20TokenHomeInitialized, error) { + event := new(ERC20TokenHomeInitialized) + if err := _ERC20TokenHome.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the ERC20TokenHome contract. +type ERC20TokenHomeMinTeleporterVersionUpdatedIterator struct { + Event *ERC20TokenHomeMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the ERC20TokenHome contract. +type ERC20TokenHomeMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*ERC20TokenHomeMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeMinTeleporterVersionUpdatedIterator{contract: _ERC20TokenHome.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeMinTeleporterVersionUpdated) + if err := _ERC20TokenHome.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*ERC20TokenHomeMinTeleporterVersionUpdated, error) { + event := new(ERC20TokenHomeMinTeleporterVersionUpdated) + if err := _ERC20TokenHome.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ERC20TokenHome contract. +type ERC20TokenHomeOwnershipTransferredIterator struct { + Event *ERC20TokenHomeOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeOwnershipTransferred represents a OwnershipTransferred event raised by the ERC20TokenHome contract. +type ERC20TokenHomeOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ERC20TokenHomeOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeOwnershipTransferredIterator{contract: _ERC20TokenHome.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeOwnershipTransferred) + if err := _ERC20TokenHome.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseOwnershipTransferred(log types.Log) (*ERC20TokenHomeOwnershipTransferred, error) { + event := new(ERC20TokenHomeOwnershipTransferred) + if err := _ERC20TokenHome.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeRemoteRegisteredIterator is returned from FilterRemoteRegistered and is used to iterate over the raw logs and unpacked data for RemoteRegistered events raised by the ERC20TokenHome contract. +type ERC20TokenHomeRemoteRegisteredIterator struct { + Event *ERC20TokenHomeRemoteRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeRemoteRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeRemoteRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeRemoteRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeRemoteRegistered represents a RemoteRegistered event raised by the ERC20TokenHome contract. +type ERC20TokenHomeRemoteRegistered struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + InitialCollateralNeeded *big.Int + TokenDecimals uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemoteRegistered is a free log retrieval operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterRemoteRegistered(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*ERC20TokenHomeRemoteRegisteredIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeRemoteRegisteredIterator{contract: _ERC20TokenHome.contract, event: "RemoteRegistered", logs: logs, sub: sub}, nil +} + +// WatchRemoteRegistered is a free log subscription operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchRemoteRegistered(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeRemoteRegistered, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeRemoteRegistered) + if err := _ERC20TokenHome.contract.UnpackLog(event, "RemoteRegistered", 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 +} + +// ParseRemoteRegistered is a log parse operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseRemoteRegistered(log types.Log) (*ERC20TokenHomeRemoteRegistered, error) { + event := new(ERC20TokenHomeRemoteRegistered) + if err := _ERC20TokenHome.contract.UnpackLog(event, "RemoteRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the ERC20TokenHome contract. +type ERC20TokenHomeTeleporterAddressPausedIterator struct { + Event *ERC20TokenHomeTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the ERC20TokenHome contract. +type ERC20TokenHomeTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenHomeTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTeleporterAddressPausedIterator{contract: _ERC20TokenHome.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeTeleporterAddressPaused) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseTeleporterAddressPaused(log types.Log) (*ERC20TokenHomeTeleporterAddressPaused, error) { + event := new(ERC20TokenHomeTeleporterAddressPaused) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the ERC20TokenHome contract. +type ERC20TokenHomeTeleporterAddressUnpausedIterator struct { + Event *ERC20TokenHomeTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the ERC20TokenHome contract. +type ERC20TokenHomeTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenHomeTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTeleporterAddressUnpausedIterator{contract: _ERC20TokenHome.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeTeleporterAddressUnpaused) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*ERC20TokenHomeTeleporterAddressUnpaused, error) { + event := new(ERC20TokenHomeTeleporterAddressUnpaused) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeTokensAndCallRoutedIterator is returned from FilterTokensAndCallRouted and is used to iterate over the raw logs and unpacked data for TokensAndCallRouted events raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensAndCallRoutedIterator struct { + Event *ERC20TokenHomeTokensAndCallRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeTokensAndCallRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeTokensAndCallRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeTokensAndCallRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeTokensAndCallRouted represents a TokensAndCallRouted event raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensAndCallRouted struct { + TeleporterMessageID [32]byte + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallRouted is a free log retrieval operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterTokensAndCallRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*ERC20TokenHomeTokensAndCallRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTokensAndCallRoutedIterator{contract: _ERC20TokenHome.contract, event: "TokensAndCallRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallRouted is a free log subscription operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchTokensAndCallRouted(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeTokensAndCallRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeTokensAndCallRouted) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensAndCallRouted", 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 +} + +// ParseTokensAndCallRouted is a log parse operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseTokensAndCallRouted(log types.Log) (*ERC20TokenHomeTokensAndCallRouted, error) { + event := new(ERC20TokenHomeTokensAndCallRouted) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensAndCallRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensAndCallSentIterator struct { + Event *ERC20TokenHomeTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeTokensAndCallSent represents a TokensAndCallSent event raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenHomeTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTokensAndCallSentIterator{contract: _ERC20TokenHome.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeTokensAndCallSent) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseTokensAndCallSent(log types.Log) (*ERC20TokenHomeTokensAndCallSent, error) { + event := new(ERC20TokenHomeTokensAndCallSent) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeTokensRoutedIterator is returned from FilterTokensRouted and is used to iterate over the raw logs and unpacked data for TokensRouted events raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensRoutedIterator struct { + Event *ERC20TokenHomeTokensRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeTokensRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeTokensRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeTokensRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeTokensRouted represents a TokensRouted event raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensRouted struct { + TeleporterMessageID [32]byte + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensRouted is a free log retrieval operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterTokensRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*ERC20TokenHomeTokensRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTokensRoutedIterator{contract: _ERC20TokenHome.contract, event: "TokensRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensRouted is a free log subscription operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchTokensRouted(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeTokensRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeTokensRouted) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensRouted", 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 +} + +// ParseTokensRouted is a log parse operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseTokensRouted(log types.Log) (*ERC20TokenHomeTokensRouted, error) { + event := new(ERC20TokenHomeTokensRouted) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensSentIterator struct { + Event *ERC20TokenHomeTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeTokensSent represents a TokensSent event raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenHomeTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTokensSentIterator{contract: _ERC20TokenHome.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeTokensSent) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseTokensSent(log types.Log) (*ERC20TokenHomeTokensSent, error) { + event := new(ERC20TokenHomeTokensSent) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensWithdrawnIterator struct { + Event *ERC20TokenHomeTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeTokensWithdrawn represents a TokensWithdrawn event raised by the ERC20TokenHome contract. +type ERC20TokenHomeTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*ERC20TokenHomeTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenHome.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeTokensWithdrawnIterator{contract: _ERC20TokenHome.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenHome.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeTokensWithdrawn) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenHome *ERC20TokenHomeFilterer) ParseTokensWithdrawn(log types.Log) (*ERC20TokenHomeTokensWithdrawn, error) { + event := new(ERC20TokenHomeTokensWithdrawn) + if err := _ERC20TokenHome.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenHome/ERC20TokenHomeUpgradeable/ERC20TokenHomeUpgradeable.go b/abi-bindings/go/ictt/TokenHome/ERC20TokenHomeUpgradeable/ERC20TokenHomeUpgradeable.go new file mode 100644 index 000000000..0e3a5107c --- /dev/null +++ b/abi-bindings/go/ictt/TokenHome/ERC20TokenHomeUpgradeable/ERC20TokenHomeUpgradeable.go @@ -0,0 +1,2833 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokenhomeupgradeable + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RemoteTokenTransferrerSettings is an auto generated low-level Go binding around an user-defined struct. +type RemoteTokenTransferrerSettings struct { + Registered bool + CollateralNeeded *big.Int + TokenMultiplier *big.Int + MultiplyOnRemote bool +} + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// ERC20TokenHomeUpgradeableMetaData contains all meta data concerning the ERC20TokenHomeUpgradeable contract. +var ERC20TokenHomeUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"enumICMInitializable\",\"name\":\"init\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"CollateralAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialCollateralNeeded\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"RemoteRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ERC20_TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addCollateral\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getRemoteTokenTransferrerSettings\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralNeeded\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"multiplyOnRemote\",\"type\":\"bool\"}],\"internalType\":\"structRemoteTokenTransferrerSettings\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getTransferredBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161483738038061483783398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b6146ea8061014d5f395ff3fe608060405234801561000f575f80fd5b5060043610610127575f3560e01c806365690038116100a9578063c8511ada1161006e578063c8511ada146102b4578063c868efaa14610388578063d2cc7a701461039b578063f2fde38b146103c2578063fd658268146103d5575f80fd5b80636569003814610232578063715018a6146102455780638da5cb5b1461024d578063909a6ac01461027d5780639731429714610291575f80fd5b80634511243e116100ef5780634511243e146101d15780634797735f146101e45780635d16225d146101f85780635eb995141461020b57806362e3901b1461021e575f80fd5b806310fe9ae81461012b578063154d625a146101745780632b0d8f18146101955780633bb03890146101aa5780634213cf78146101bd575b5f80fd5b7f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e601546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b61018761018236600461368c565b6103e8565b60405190815260200161016b565b6101a86101a33660046136ba565b610430565b005b6101a86101b83660046136e3565b610532565b5f8051602061461583398151915254610187565b6101a86101df3660046136ba565b610646565b6101875f8051602061467583398151915281565b6101a8610206366004613747565b610735565b6101a8610219366004613776565b610751565b6101875f8051602061461583398151915281565b6101a861024036600461378d565b610765565b6101a861078e565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610157565b6101875f8051602061469583398151915281565b6102a461029f3660046136ba565b6107a1565b604051901515815260200161016b565b6103516102c236600461368c565b60408051608080820183525f808352602080840182905283850182905260609384018290529581525f8051602061463583398151915286528381206001600160a01b039590951681529385529282902082519384018352805460ff9081161515855260018201549585019590955260028101549284019290925260039091015490921615159181019190915290565b60405161016b9190815115158152602080830151908201526040808301519082015260609182015115159181019190915260800190565b6101a86103963660046137d3565b6107c1565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0254610187565b6101a86103d03660046136ba565b61097e565b6101a86103e3366004613854565b6109b8565b5f8281527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03851684529091529020545b92915050565b5f805160206146958339815191526104466109c8565b6001600160a01b0382166104755760405162461bcd60e51b815260040161046c90613889565b60405180910390fd5b61047f81836109d0565b156104e25760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b606482015260840161046c565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156105765750825b90505f826001600160401b031660011480156105915750303b155b90508115801561059f575080155b156105bd5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156105e757845460ff60401b1916600160401b1785555b6105f48a8a8a8a8a6109f1565b831561063a57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050505050565b5f8051602061469583398151915261065c6109c8565b6001600160a01b0382166106825760405162461bcd60e51b815260040161046c90613889565b61068c81836109d0565b6106ea5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b606482015260840161046c565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b61074d61074736849003840184613989565b82610a16565b5050565b6107596109c8565b61076281610c27565b50565b61074d61077d5f805160206146158339815191525490565b303361078886613a8b565b85610dbf565b610796610fcb565b61079f5f611026565b565b5f5f805160206146958339815191526107ba81846109d0565b9392505050565b6107c9611096565b5f5f8051602061469583398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610834573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108589190613b59565b10156108bf5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b606482015260840161046c565b6108c981336109d0565b1561092f5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b606482015260840161046c565b61096f858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506110e092505050565b506109786114d3565b50505050565b610986610fcb565b6001600160a01b0381166109af57604051631e4fbdf760e01b81525f600482015260240161046c565b61076281611026565b6109c38383836114fd565b505050565b61079f610fcb565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b6109f96116ed565b610a068585858585611736565b610a0f8261175b565b5050505050565b5f805160206146558339815191528054600114610a455760405162461bcd60e51b815260040161046c90613b70565b60028155610a5283611791565b60e08301516001600160a01b031615610a7d5760405162461bcd60e51b815260040161046c90613bb4565b5f80610a9b855f01518660200151868860600151896080015161183a565b915091505f604051806040016040528060016004811115610abe57610abe613bfa565b8152602001604051806040016040528089604001516001600160a01b0316815260200186815250604051602001610af59190613c0e565b60405160208183030381529060405281525090505f610bd46040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b606001516001600160a01b031681526020018781525081526020018960c0015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b604051908082528060200260200182016040528015610ba6578160200160208202803683370190505b50815260200184604051602001610bbd9190613c7b565b6040516020818303038152906040528152506119ff565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb528987604051610c12929190613cbd565b60405180910390a35050600190925550505050565b5f8051602061469583398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610c7b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9f9190613b59565b600283015490915081841115610d115760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b606482015260840161046c565b808411610d865760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e00606482015260840161046c565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b5f805160206146558339815191528054600114610dee5760405162461bcd60e51b815260040161046c90613b70565b60028155610dfb83611b1a565b60c08301516001600160a01b031615610e265760405162461bcd60e51b815260040161046c90613bb4565b5f80610e46855f015186602001518688610100015189610120015161183a565b915091505f604051806040016040528060026004811115610e6957610e69613bfa565b81526020016040518061010001604052808c81526020018b6001600160a01b031681526020018a6001600160a01b0316815260200189604001516001600160a01b03168152602001868152602001896060015181526020018960a0015181526020018960e001516001600160a01b0316815250604051602001610eec9190613d3e565b60405160208183030381529060405281525090505f610f756040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b61010001516001600160a01b03168152602001878152508152602001896080015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b9050876001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168987604051610fb3929190613ddc565b60405180910390a35050600190925550505050505050565b33610ffd7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03161461079f5760405163118cdaa760e01b815233600482015260240161046c565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008054600119016110da57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f5f8051602061461583398151915290505f828060200190518101906111069190613f00565b905060018151600481111561111d5761111d613bfa565b03611165575f816020015180602001905181019061113b9190613f88565b90505f61114d87878460200151611cff565b905061115c825f015182611d8a565b50505050505050565b60028151600481111561117a5761117a613bfa565b03611293575f81602001518060200190518101906111989190613fc0565b90505f6111aa87878460800151611cff565b825190915087146112105760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a206d69736d61746368656420736f7572636520626c6f60448201526918dad8da185a5b88125160b21b606482015260840161046c565b856001600160a01b031682602001516001600160a01b0316146112895760405162461bcd60e51b815260206004820152602b60248201527f546f6b656e486f6d653a206d69736d617463686564206f726967696e2073656e60448201526a646572206164647265737360a81b606482015260840161046c565b61115c8282611ded565b6003815160048111156112a8576112a8613bfa565b0361137c575f81602001518060200190518101906112c6919061408a565b90505f806112de888885606001518660800151611fcd565b91509150611372604051806101000160405280855f0151815260200185602001516001600160a01b0316815260200185604001516001600160a01b03168152602001876001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018381526020015f81526020018560a0015181526020018560c001516001600160a01b031681525083612078565b5050505050505050565b60048151600481111561139157611391613bfa565b0361148c575f81602001518060200190518101906113af9190614123565b90505f806113c888888560800151866101400151611fcd565b915091506113728888855f01516040518061016001604052808860200151815260200188604001516001600160a01b0316815260200188606001516001600160a01b031681526020018860a00151815260200188610100015181526020018860c0015181526020018861012001516001600160a01b031681526020018860e001516001600160a01b031681526020018a6001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018681526020015f81525086612203565b5f815160048111156114a0576114a0613bfa565b03610a0f575f81602001518060200190518101906114be919061421b565b90506114cb8686836123e0565b505050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b5f80516020614655833981519152805460011461152c5760405162461bcd60e51b815260040161046c90613b70565b60028082555f8581525f80516020614635833981519152602090815260408083206001600160a01b03881684528252918290208251608081018452815460ff9081161515808352600184015494830194909452948201549381019390935260030154909216151560608201525f80516020614615833981519152916115c35760405162461bcd60e51b815260040161046c90614281565b5f8160200151116116205760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20636f6c6c61746572616c206e656564656044820152601960fa1b606482015260840161046c565b611629846127e7565b93505f80826020015186106116585760208301515f925061164a90876142ca565b90508260200151955061166b565b85836020015161166891906142ca565b91505b5f88815260028501602090815260408083206001600160a01b038b168085529083529281902060010185905580518981529182018590528a917f6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6910160405180910390a380156116df576116df3382611d8a565b505060019092555050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661079f57604051631afcd79f60e31b815260040160405180910390fd5b61173e6116ed565b61174985858561280e565b611751612829565b610a0f8282612839565b6117636116ed565b5f8051602061467583398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b60408101516001600160a01b03166117f55760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20726563697069656e74206164647265736044820152607360f81b606482015260840161046c565b5f8160c00151116118185760405162461bcd60e51b815260040161046c906142dd565b60a0810151156107625760405162461bcd60e51b815260040161046c9061431f565b5f8581525f80516020614635833981519152602090815260408083206001600160a01b038816845282528083208151608081018352815460ff90811615158083526001840154958301959095526002830154938201939093526003909101549091161515606082015282915f8051602061461583398151915291906118d15760405162461bcd60e51b815260040161046c90614281565b6020810151156119335760405162461bcd60e51b815260206004820152602760248201527f546f6b656e486f6d653a20636f6c6c61746572616c206e656564656420666f726044820152662072656d6f746560c81b606482015260840161046c565b61193c876127e7565b965084156119525761194f8633876129a0565b94505b5f611966826040015183606001518a612af9565b90505f81116119b75760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f207363616c656420616d6f756e74000000604482015260640161046c565b5f8a815260038401602090815260408083206001600160a01b038d168452909152812080548392906119ea908490614360565b90915550909a95995094975050505050505050565b5f80611a09612b0f565b60408401516020015190915015611aae576040830151516001600160a01b0316611a8b5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b606482015260840161046c565b604083015160208101519051611aae916001600160a01b03909116908390612bff565b604051630624488560e41b81526001600160a01b03821690636244885090611ada908690600401614373565b6020604051808303815f875af1158015611af6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107ba9190613b59565b60408101516001600160a01b0316611b875760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420636f6e7472616044820152696374206164647265737360b01b606482015260840161046c565b5f816080015111611baa5760405162461bcd60e51b815260040161046c906142dd565b5f8160a0015111611c095760405162461bcd60e51b815260206004820152602360248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420676173206c696044820152621b5a5d60ea1b606482015260840161046c565b80608001518160a0015110611c6f5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420726563697069656e7420676173604482015265081b1a5b5a5d60d21b606482015260840161046c565b60e08101516001600160a01b0316611cdc5760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f2066616c6c6261636b20726563697069656044820152696e74206164647265737360b01b606482015260840161046c565b610140810151156107625760405162461bcd60e51b815260040161046c9061431f565b5f8381525f80516020614635833981519152602090815260408083206001600160a01b038616845282528083208151608081018352815460ff9081161515825260018301549482019490945260028201549281019290925260030154909116151560608201525f8051602061461583398151915290611d8081878787612c86565b9695505050505050565b6040518181525f80516020614675833981519152906001600160a01b038416907f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b9060200160405180910390a280546109c3906001600160a01b03168484612d7d565b5f80516020614675833981519152805460608401516001600160a01b0390911690611e1a90829085612bff565b5f845f01518560200151866040015184878960a00151604051602401611e459695949392919061442a565b60408051601f198184030181529190526020810180516001600160e01b03166394395edd60e01b17905260c086015160608701519192505f91611e89919084612ddc565b6060870151604051636eb1769f60e11b81523060048201526001600160a01b0391821660248201529192505f919085169063dd62ed3e90604401602060405180830381865afa158015611ede573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f029190613b59565b9050611f138488606001515f612de9565b8115611f655786606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff487604051611f5891815260200190565b60405180910390a2611fad565b86606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb087604051611fa491815260200190565b60405180910390a25b801561115c5760e087015161115c906001600160a01b0386169083612d7d565b5f8481525f80516020614635833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff90811615158252600183015494820194909452600282015492810192909252600301549091161515606082015281905f805160206146158339815191529082612051828a8a8a612c86565b90505f6120678360400151846060015189612e78565b919a91995090975050505050505050565b5f8051602061465583398151915280546001146120a75760405162461bcd60e51b815260040161046c90613b70565b600281556120b483611791565b5f6120cc845f01518560200151858760800151612e85565b9050805f036120e9576120e38460e0015184611d8a565b506121fb565b604080518082019091525f908060018152602001604051806040016040528088604001516001600160a01b031681526020018581525060405160200161212f9190613c0e565b60405160208183030381529060405281525090505f6121bb6040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a606001516001600160a01b031681526020018a6080015181525081526020018860c0015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b9050807f825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf087856040516121ef929190613cbd565b60405180910390a25050505b600190555050565b5f8051602061465583398151915280546001146122325760405162461bcd60e51b815260040161046c90613b70565b6002815561223f83611b1a565b5f612258845f0151856020015185876101200151612e85565b9050805f036122755761226f8460c0015184611d8a565b506123d5565b604080518082019091525f9080600281526020016040518061010001604052808b81526020018a6001600160a01b03168152602001896001600160a01b0316815260200188604001516001600160a01b03168152602001858152602001886060015181526020018860a0015181526020018860e001516001600160a01b03168152506040516020016123079190613d3e565b60405160208183030381529060405281525090505f6123956040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a61010001516001600160a01b031681526020018a61012001518152508152602001886080015181526020015f6001600160401b03811115610b7d57610b7d6138d7565b9050807f42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb3087856040516123c9929190613ddc565b60405180910390a25050505b600190555050505050565b5f80516020614615833981519152836124475760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a207a65726f2072656d6f746520626c6f636b636861696044820152631b88125160e21b606482015260840161046c565b805484036124af5760405162461bcd60e51b815260206004820152602f60248201527f546f6b656e486f6d653a2063616e6e6f742072656769737465722072656d6f7460448201526e329037b71039b0b6b29031b430b4b760891b606482015260840161046c565b6001600160a01b03831661251e5760405162461bcd60e51b815260206004820152603060248201527f546f6b656e486f6d653a207a65726f2072656d6f746520746f6b656e2074726160448201526f6e73666572726572206164647265737360801b606482015260840161046c565b5f84815260028201602090815260408083206001600160a01b038716845290915290205460ff161561259e5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f746520616c726561647920726567697374604482015263195c995960e21b606482015260840161046c565b6012826040015160ff1611156126085760405162461bcd60e51b815260206004820152602960248201527f546f6b656e486f6d653a2072656d6f746520746f6b656e20646563696d616c73604482015268040e8dede40d0d2ced60bb1b606482015260840161046c565b6001810154602083015160ff908116600160a01b909204161461267c5760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420686f6d6520746f6b656e20646560448201526563696d616c7360d01b606482015260840161046c565b5f8061269d8360010160149054906101000a900460ff168560400151612ff6565b915091505f6126b08383875f0151612e78565b90508180156126ca575084516126c790849061447e565b15155b156126dd576126da600182614360565b90505b6040518060800160405280600115158152602001828152602001848152602001831515815250846002015f8981526020019081526020015f205f886001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003015f6101000a81548160ff021916908315150217905550905050856001600160a01b0316877ff229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b908388604001516040516127d692919091825260ff16602082015260400190565b60405180910390a350505050505050565b5f8051602061467583398151915280545f91906107ba906001600160a01b031633856129a0565b6128166116ed565b612820838261303e565b6109c382613060565b6128316116ed565b61079f613071565b6128416116ed565b6001600160a01b0382166128975760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f20746f6b656e2061646472657373000000604482015260640161046c565b60128160ff1611156128f65760405162461bcd60e51b815260206004820152602260248201527f546f6b656e486f6d653a20746f6b656e20646563696d616c7320746f6f2068696044820152610ced60f31b606482015260840161046c565b5f5f8051602061461583398151915290506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561294a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061296e9190613b59565b8155600101805460ff909216600160a01b026001600160a81b03199092166001600160a01b0390931692909217179055565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa1580156129e6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a0a9190613b59565b9050612a216001600160a01b038616853086613085565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612a65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a899190613b59565b9050818111612aef5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840161046c565b611d8082826142ca565b5f612b0784848460016130be565b949350505050565b5f8051602061469583398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b8d9190614491565b9050612b9982826109d0565b1561042a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b606482015260840161046c565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612c4c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c709190613b59565b90506109788484612c818585614360565b612de9565b83515f90612ca65760405162461bcd60e51b815260040161046c90614281565b602085015115612d045760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f7465206e6f7420636f6c6c61746572616c6044820152631a5e995960e21b606482015260840161046c565b612d0f8484846130e5565b5f612d238660400151876060015185612e78565b90505f8111612d745760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e486f6d653a207a65726f20746f6b656e20616d6f756e7400000000604482015260640161046c565b95945050505050565b6040516001600160a01b038381166024830152604482018390526109c391859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506131d2565b5f612b07845f8585613233565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612e3a8482613303565b610978576040516001600160a01b0384811660248301525f6044830152612e6e91869182169063095ea7b390606401612daa565b61097884826131d2565b5f612b078484845f6130be565b5f8481525f80516020614635833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff9081161580158352600184015495830195909552600283015493820193909352600390910154909116151560608201525f805160206146158339815191529180612f0b57505f8160200151115b15612f1a575f92505050612b07565b838511612f7e5760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e486f6d653a20696e73756666696369656e7420616d6f756e74207460448201526b6f20636f766572206665657360a01b606482015260840161046c565b612f8884866142ca565b94505f612f9e8260400151836060015188612af9565b9050805f03612fb2575f9350505050612b07565b5f88815260038401602090815260408083206001600160a01b038b16845290915281208054839290612fe5908490614360565b909155509098975050505050505050565b5f8060ff8085169084161181816130195761301185876144ac565b60ff16613027565b61302386866144ac565b60ff165b61303290600a6145a5565b96919550909350505050565b6130466116ed565b61304e6133a0565b6130566133b0565b61074d82826133b8565b6130686116ed565b6107628161353c565b5f5f805160206146558339815191526114f6565b6040516001600160a01b0384811660248301528381166044830152606482018390526109789186918216906323b872dd90608401612daa565b5f811515841515036130db576130d485846145b0565b9050612b07565b612d7485846145c7565b5f8381527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03861684529091529020545f80516020614615833981519152908281101561319c5760405162461bcd60e51b815260206004820152602e60248201527f546f6b656e486f6d653a20696e73756666696369656e7420746f6b656e20747260448201526d616e736665722062616c616e636560901b606482015260840161046c565b6131a683826142ca565b5f9586526003909201602090815260408087206001600160a01b03909616875294905250919092205550565b5f6131e66001600160a01b03841683613544565b905080515f1415801561320a57508080602001905181019061320891906145da565b155b156109c357604051635274afe760e01b81526001600160a01b038416600482015260240161046c565b5f845a10156132845760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e74206761730000000000604482015260640161046c565b834710156132d45760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c7565000000604482015260640161046c565b826001600160a01b03163b5f036132ec57505f612b07565b5f805f84516020860188888bf19695505050505050565b5f805f846001600160a01b03168460405161331e91906145f9565b5f604051808303815f865af19150503d805f8114613357576040519150601f19603f3d011682016040523d82523d5f602084013e61335c565b606091505b509150915081801561338657508051158061338657508080602001905181019061338691906145da565b8015612d745750505050506001600160a01b03163b151590565b6133a86116ed565b61079f613551565b61079f6116ed565b6133c06116ed565b6001600160a01b03821661343c5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840161046c565b5f5f8051602061469583398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa15801561348e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134b29190613b59565b1161351a5760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b606482015260840161046c565b81546001600160a01b0319166001600160a01b03821617825561097883610c27565b6109866116ed565b60606107ba83835f613559565b6114d36116ed565b60608147101561357e5760405163cd78605960e01b815230600482015260240161046c565b5f80856001600160a01b0316848660405161359991906145f9565b5f6040518083038185875af1925050503d805f81146135d3576040519150601f19603f3d011682016040523d82523d5f602084013e6135d8565b606091505b5091509150611d808683836060826135f8576135f38261363f565b6107ba565b815115801561360f57506001600160a01b0384163b155b1561363857604051639996b31560e01b81526001600160a01b038516600482015260240161046c565b50806107ba565b80511561364f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610762575f80fd5b803561368781613668565b919050565b5f806040838503121561369d575f80fd5b8235915060208301356136af81613668565b809150509250929050565b5f602082840312156136ca575f80fd5b81356107ba81613668565b60ff81168114610762575f80fd5b5f805f805f60a086880312156136f7575f80fd5b853561370281613668565b9450602086013561371281613668565b935060408601359250606086013561372981613668565b91506080860135613739816136d5565b809150509295509295909350565b5f8082840361012081121561375a575f80fd5b61010080821215613769575f80fd5b9395938601359450505050565b5f60208284031215613786575f80fd5b5035919050565b5f806040838503121561379e575f80fd5b82356001600160401b038111156137b3575f80fd5b830161016081860312156137c5575f80fd5b946020939093013593505050565b5f805f80606085870312156137e6575f80fd5b8435935060208501356137f881613668565b925060408501356001600160401b0380821115613813575f80fd5b818701915087601f830112613826575f80fd5b813581811115613834575f80fd5b886020828501011115613845575f80fd5b95989497505060200194505050565b5f805f60608486031215613866575f80fd5b83359250602084013561387881613668565b929592945050506040919091013590565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b60405161010081016001600160401b038111828210171561390e5761390e6138d7565b60405290565b60405161016081016001600160401b038111828210171561390e5761390e6138d7565b604080519081016001600160401b038111828210171561390e5761390e6138d7565b604051601f8201601f191681016001600160401b0381118282101715613981576139816138d7565b604052919050565b5f610100828403121561399a575f80fd5b6139a26138eb565b8235815260208301356139b481613668565b602082015260408301356139c781613668565b60408201526139d86060840161367c565b60608201526080830135608082015260a083013560a082015260c083013560c0820152613a0760e0840161367c565b60e08201529392505050565b5f6001600160401b03821115613a2b57613a2b6138d7565b50601f01601f191660200190565b5f82601f830112613a48575f80fd5b8135613a5b613a5682613a13565b613959565b818152846020838601011115613a6f575f80fd5b816020850160208301375f918101602001919091529392505050565b5f6101608236031215613a9c575f80fd5b613aa4613914565b82358152613ab46020840161367c565b6020820152613ac56040840161367c565b604082015260608301356001600160401b03811115613ae2575f80fd5b613aee36828601613a39565b6060830152506080830135608082015260a083013560a0820152613b1460c0840161367c565b60c0820152613b2560e0840161367c565b60e0820152610100613b3881850161367c565b90820152610120838101359082015261014092830135928101929092525090565b5f60208284031215613b69575f80fd5b5051919050565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b60208082526026908201527f546f6b656e486f6d653a206e6f6e2d7a65726f206d756c74692d686f702066616040820152656c6c6261636b60d01b606082015260800190565b634e487b7160e01b5f52602160045260245ffd5b81516001600160a01b03168152602080830151908201526040810161042a565b5f5b83811015613c48578181015183820152602001613c30565b50505f910152565b5f8151808452613c67816020860160208601613c2e565b601f01601f19169290920160200192915050565b602081525f825160058110613c9e57634e487b7160e01b5f52602160045260245ffd5b806020840152506020830151604080840152612b076060840182613c50565b5f6101208201905083518252602084015160018060a01b03808216602085015280604087015116604085015280606087015116606085015250506080840151608083015260a084015160a083015260c084015160c083015260e0840151613d2f60e08401826001600160a01b03169052565b50826101008301529392505050565b60208152815160208201525f602083015160018060a01b03808216604085015280604086015116606085015250506060830151613d8660808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c0850152613dad610120850183613c50565b915060c085015160e085015260e0850151613dd2828601826001600160a01b03169052565b5090949350505050565b60408152825160408201525f6020840151613e0260608401826001600160a01b03169052565b5060408401516001600160a01b03166080830152606084015161016060a08401819052613e336101a0850183613c50565b9150608086015160c085015260a086015160e085015260c0860151610100613e65818701836001600160a01b03169052565b60e08801519150610120613e83818801846001600160a01b03169052565b90880151915061014090613ea1878301846001600160a01b03169052565b880151928601929092525090940151610180830152506020015290565b5f82601f830112613ecd575f80fd5b8151613edb613a5682613a13565b818152846020838601011115613eef575f80fd5b612b07826020830160208701613c2e565b5f60208284031215613f10575f80fd5b81516001600160401b0380821115613f26575f80fd5b9083019060408286031215613f39575f80fd5b613f41613937565b825160058110613f4f575f80fd5b8152602083015182811115613f62575f80fd5b613f6e87828601613ebe565b60208301525095945050505050565b805161368781613668565b5f60408284031215613f98575f80fd5b613fa0613937565b8251613fab81613668565b81526020928301519281019290925250919050565b5f60208284031215613fd0575f80fd5b81516001600160401b0380821115613fe6575f80fd5b908301906101008286031215613ffa575f80fd5b6140026138eb565b8251815261401260208401613f7d565b602082015261402360408401613f7d565b604082015261403460608401613f7d565b60608201526080830151608082015260a083015182811115614054575f80fd5b61406087828601613ebe565b60a08301525060c083015160c082015261407c60e08401613f7d565b60e082015295945050505050565b5f60e0828403121561409a575f80fd5b60405160e081018181106001600160401b03821117156140bc576140bc6138d7565b6040528251815260208301516140d181613668565b602082015260408301516140e481613668565b80604083015250606083015160608201526080830151608082015260a083015160a082015260c083015161411781613668565b60c08201529392505050565b5f60208284031215614133575f80fd5b81516001600160401b0380821115614149575f80fd5b90830190610160828603121561415d575f80fd5b614165613914565b61416e83613f7d565b81526020830151602082015261418660408401613f7d565b604082015261419760608401613f7d565b60608201526080830151608082015260a0830151828111156141b7575f80fd5b6141c387828601613ebe565b60a08301525060c083015160c08201526141df60e08401613f7d565b60e0820152610100838101519082015261012091506141ff828401613f7d565b9181019190915261014091820151918101919091529392505050565b5f6060828403121561422b575f80fd5b604051606081018181106001600160401b038211171561424d5761424d6138d7565b604052825181526020830151614262816136d5565b60208201526040830151614275816136d5565b60408201529392505050565b6020808252818101527f546f6b656e486f6d653a2072656d6f7465206e6f742072656769737465726564604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561042a5761042a6142b6565b60208082526022908201527f546f6b656e486f6d653a207a65726f20726571756972656420676173206c696d6040820152611a5d60f21b606082015260800190565b60208082526021908201527f546f6b656e486f6d653a206e6f6e2d7a65726f207365636f6e646172792066656040820152606560f81b606082015260800190565b8082018082111561042a5761042a6142b6565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b80841015614400578451831682529385019360019390930192908501906143de565b5060a0880151878203601f190160e0890152945061441e8186613c50565b98975050505050505050565b8681526001600160a01b0386811660208301528581166040830152841660608201526080810183905260c060a082018190525f9061441e90830184613c50565b634e487b7160e01b5f52601260045260245ffd5b5f8261448c5761448c61446a565b500690565b5f602082840312156144a1575f80fd5b81516107ba81613668565b60ff828116828216039081111561042a5761042a6142b6565b600181815b808511156144ff57815f19048211156144e5576144e56142b6565b808516156144f257918102915b93841c93908002906144ca565b509250929050565b5f826145155750600161042a565b8161452157505f61042a565b816001811461453757600281146145415761455d565b600191505061042a565b60ff841115614552576145526142b6565b50506001821b61042a565b5060208310610133831016604e8410600b8410161715614580575081810a61042a565b61458a83836144c5565b805f190482111561459d5761459d6142b6565b029392505050565b5f6107ba8383614507565b808202811582820484141761042a5761042a6142b6565b5f826145d5576145d561446a565b500490565b5f602082840312156145ea575f80fd5b815180151581146107ba575f80fd5b5f825161460a818460208701613c2e565b919091019291505056fe9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e6009316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e602d2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500914a9547f6c3ddce1d5efbd9e687708f0d1d408ce129e8e1a88bce4f40e29500de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a264697066735822122016e65ba67248c4f93dbcf6f4583aab02f58c918fe7ba5ee9fab67075ccd6dd3c64736f6c63430008190033", +} + +// ERC20TokenHomeUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenHomeUpgradeableMetaData.ABI instead. +var ERC20TokenHomeUpgradeableABI = ERC20TokenHomeUpgradeableMetaData.ABI + +// ERC20TokenHomeUpgradeableBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenHomeUpgradeableMetaData.Bin instead. +var ERC20TokenHomeUpgradeableBin = ERC20TokenHomeUpgradeableMetaData.Bin + +// DeployERC20TokenHomeUpgradeable deploys a new Ethereum contract, binding an instance of ERC20TokenHomeUpgradeable to it. +func DeployERC20TokenHomeUpgradeable(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *ERC20TokenHomeUpgradeable, error) { + parsed, err := ERC20TokenHomeUpgradeableMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20TokenHomeUpgradeableBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenHomeUpgradeable{ERC20TokenHomeUpgradeableCaller: ERC20TokenHomeUpgradeableCaller{contract: contract}, ERC20TokenHomeUpgradeableTransactor: ERC20TokenHomeUpgradeableTransactor{contract: contract}, ERC20TokenHomeUpgradeableFilterer: ERC20TokenHomeUpgradeableFilterer{contract: contract}}, nil +} + +// ERC20TokenHomeUpgradeable is an auto generated Go binding around an Ethereum contract. +type ERC20TokenHomeUpgradeable struct { + ERC20TokenHomeUpgradeableCaller // Read-only binding to the contract + ERC20TokenHomeUpgradeableTransactor // Write-only binding to the contract + ERC20TokenHomeUpgradeableFilterer // Log filterer for contract events +} + +// ERC20TokenHomeUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenHomeUpgradeableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenHomeUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenHomeUpgradeableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenHomeUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenHomeUpgradeableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenHomeUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenHomeUpgradeableSession struct { + Contract *ERC20TokenHomeUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenHomeUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenHomeUpgradeableCallerSession struct { + Contract *ERC20TokenHomeUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenHomeUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenHomeUpgradeableTransactorSession struct { + Contract *ERC20TokenHomeUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenHomeUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenHomeUpgradeableRaw struct { + Contract *ERC20TokenHomeUpgradeable // Generic contract binding to access the raw methods on +} + +// ERC20TokenHomeUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenHomeUpgradeableCallerRaw struct { + Contract *ERC20TokenHomeUpgradeableCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenHomeUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenHomeUpgradeableTransactorRaw struct { + Contract *ERC20TokenHomeUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenHomeUpgradeable creates a new instance of ERC20TokenHomeUpgradeable, bound to a specific deployed contract. +func NewERC20TokenHomeUpgradeable(address common.Address, backend bind.ContractBackend) (*ERC20TokenHomeUpgradeable, error) { + contract, err := bindERC20TokenHomeUpgradeable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeable{ERC20TokenHomeUpgradeableCaller: ERC20TokenHomeUpgradeableCaller{contract: contract}, ERC20TokenHomeUpgradeableTransactor: ERC20TokenHomeUpgradeableTransactor{contract: contract}, ERC20TokenHomeUpgradeableFilterer: ERC20TokenHomeUpgradeableFilterer{contract: contract}}, nil +} + +// NewERC20TokenHomeUpgradeableCaller creates a new read-only instance of ERC20TokenHomeUpgradeable, bound to a specific deployed contract. +func NewERC20TokenHomeUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenHomeUpgradeableCaller, error) { + contract, err := bindERC20TokenHomeUpgradeable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableCaller{contract: contract}, nil +} + +// NewERC20TokenHomeUpgradeableTransactor creates a new write-only instance of ERC20TokenHomeUpgradeable, bound to a specific deployed contract. +func NewERC20TokenHomeUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenHomeUpgradeableTransactor, error) { + contract, err := bindERC20TokenHomeUpgradeable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTransactor{contract: contract}, nil +} + +// NewERC20TokenHomeUpgradeableFilterer creates a new log filterer instance of ERC20TokenHomeUpgradeable, bound to a specific deployed contract. +func NewERC20TokenHomeUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenHomeUpgradeableFilterer, error) { + contract, err := bindERC20TokenHomeUpgradeable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableFilterer{contract: contract}, nil +} + +// bindERC20TokenHomeUpgradeable binds a generic wrapper to an already deployed contract. +func bindERC20TokenHomeUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenHomeUpgradeableMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenHomeUpgradeable.Contract.ERC20TokenHomeUpgradeableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.ERC20TokenHomeUpgradeableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.ERC20TokenHomeUpgradeableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenHomeUpgradeable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.contract.Transact(opts, method, params...) +} + +// ERC20TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x4797735f. +// +// Solidity: function ERC20_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) ERC20TOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "ERC20_TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ERC20TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x4797735f. +// +// Solidity: function ERC20_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) ERC20TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.ERC20TOKENHOMESTORAGELOCATION(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// ERC20TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x4797735f. +// +// Solidity: function ERC20_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) ERC20TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.ERC20TOKENHOMESTORAGELOCATION(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) TOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.TOKENHOMESTORAGELOCATION(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.TOKENHOMESTORAGELOCATION(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetBlockchainID(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetBlockchainID(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetMinTeleporterVersion(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetMinTeleporterVersion(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) GetRemoteTokenTransferrerSettings(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "getRemoteTokenTransferrerSettings", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(RemoteTokenTransferrerSettings), err + } + + out0 := *abi.ConvertType(out[0], new(RemoteTokenTransferrerSettings)).(*RemoteTokenTransferrerSettings) + + return out0, err + +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetRemoteTokenTransferrerSettings(&_ERC20TokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetRemoteTokenTransferrerSettings(&_ERC20TokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) GetTokenAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "getTokenAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) GetTokenAddress() (common.Address, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetTokenAddress(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) GetTokenAddress() (common.Address, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetTokenAddress(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) GetTransferredBalance(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "getTransferredBalance", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetTransferredBalance(&_ERC20TokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _ERC20TokenHomeUpgradeable.Contract.GetTransferredBalance(&_ERC20TokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenHomeUpgradeable.Contract.IsTeleporterAddressPaused(&_ERC20TokenHomeUpgradeable.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenHomeUpgradeable.Contract.IsTeleporterAddressPaused(&_ERC20TokenHomeUpgradeable.CallOpts, teleporterAddress) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenHomeUpgradeable.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) Owner() (common.Address, error) { + return _ERC20TokenHomeUpgradeable.Contract.Owner(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableCallerSession) Owner() (common.Address, error) { + return _ERC20TokenHomeUpgradeable.Contract.Owner(&_ERC20TokenHomeUpgradeable.CallOpts) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xfd658268. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) AddCollateral(opts *bind.TransactOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "addCollateral", remoteBlockchainID, remoteTokenTransferrerAddress, amount) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xfd658268. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.AddCollateral(&_ERC20TokenHomeUpgradeable.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress, amount) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xfd658268. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.AddCollateral(&_ERC20TokenHomeUpgradeable.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress, amount) +} + +// Initialize is a paid mutator transaction binding the contract method 0x3bb03890. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address tokenAddress, uint8 tokenDecimals) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) Initialize(opts *bind.TransactOpts, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, tokenAddress common.Address, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "initialize", teleporterRegistryAddress, teleporterManager, minTeleporterVersion, tokenAddress, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0x3bb03890. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address tokenAddress, uint8 tokenDecimals) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, tokenAddress common.Address, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.Initialize(&_ERC20TokenHomeUpgradeable.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, tokenAddress, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0x3bb03890. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address tokenAddress, uint8 tokenDecimals) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, tokenAddress common.Address, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.Initialize(&_ERC20TokenHomeUpgradeable.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, tokenAddress, tokenDecimals) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.PauseTeleporterAddress(&_ERC20TokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.PauseTeleporterAddress(&_ERC20TokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.ReceiveTeleporterMessage(&_ERC20TokenHomeUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.ReceiveTeleporterMessage(&_ERC20TokenHomeUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.RenounceOwnership(&_ERC20TokenHomeUpgradeable.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.RenounceOwnership(&_ERC20TokenHomeUpgradeable.TransactOpts) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) Send(opts *bind.TransactOpts, input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "send", input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.Send(&_ERC20TokenHomeUpgradeable.TransactOpts, input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.Send(&_ERC20TokenHomeUpgradeable.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "sendAndCall", input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.SendAndCall(&_ERC20TokenHomeUpgradeable.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.SendAndCall(&_ERC20TokenHomeUpgradeable.TransactOpts, input, amount) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.TransferOwnership(&_ERC20TokenHomeUpgradeable.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.TransferOwnership(&_ERC20TokenHomeUpgradeable.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.UnpauseTeleporterAddress(&_ERC20TokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.UnpauseTeleporterAddress(&_ERC20TokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.UpdateMinTeleporterVersion(&_ERC20TokenHomeUpgradeable.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenHomeUpgradeable.Contract.UpdateMinTeleporterVersion(&_ERC20TokenHomeUpgradeable.TransactOpts, version) +} + +// ERC20TokenHomeUpgradeableCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableCallFailedIterator struct { + Event *ERC20TokenHomeUpgradeableCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableCallFailed represents a CallFailed event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenHomeUpgradeableCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableCallFailedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableCallFailed) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseCallFailed(log types.Log) (*ERC20TokenHomeUpgradeableCallFailed, error) { + event := new(ERC20TokenHomeUpgradeableCallFailed) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableCallSucceededIterator struct { + Event *ERC20TokenHomeUpgradeableCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableCallSucceeded represents a CallSucceeded event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenHomeUpgradeableCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableCallSucceededIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableCallSucceeded) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseCallSucceeded(log types.Log) (*ERC20TokenHomeUpgradeableCallSucceeded, error) { + event := new(ERC20TokenHomeUpgradeableCallSucceeded) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableCollateralAddedIterator is returned from FilterCollateralAdded and is used to iterate over the raw logs and unpacked data for CollateralAdded events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableCollateralAddedIterator struct { + Event *ERC20TokenHomeUpgradeableCollateralAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableCollateralAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableCollateralAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableCollateralAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableCollateralAdded represents a CollateralAdded event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableCollateralAdded struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + Amount *big.Int + Remaining *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollateralAdded is a free log retrieval operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterCollateralAdded(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*ERC20TokenHomeUpgradeableCollateralAddedIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableCollateralAddedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "CollateralAdded", logs: logs, sub: sub}, nil +} + +// WatchCollateralAdded is a free log subscription operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchCollateralAdded(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableCollateralAdded, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableCollateralAdded) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "CollateralAdded", 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 +} + +// ParseCollateralAdded is a log parse operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseCollateralAdded(log types.Log) (*ERC20TokenHomeUpgradeableCollateralAdded, error) { + event := new(ERC20TokenHomeUpgradeableCollateralAdded) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "CollateralAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableInitializedIterator struct { + Event *ERC20TokenHomeUpgradeableInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableInitialized represents a Initialized event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*ERC20TokenHomeUpgradeableInitializedIterator, error) { + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableInitializedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableInitialized) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableInitialized) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseInitialized(log types.Log) (*ERC20TokenHomeUpgradeableInitialized, error) { + event := new(ERC20TokenHomeUpgradeableInitialized) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableMinTeleporterVersionUpdatedIterator struct { + Event *ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*ERC20TokenHomeUpgradeableMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableMinTeleporterVersionUpdatedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated, error) { + event := new(ERC20TokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableOwnershipTransferredIterator struct { + Event *ERC20TokenHomeUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ERC20TokenHomeUpgradeableOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableOwnershipTransferredIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableOwnershipTransferred) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*ERC20TokenHomeUpgradeableOwnershipTransferred, error) { + event := new(ERC20TokenHomeUpgradeableOwnershipTransferred) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableRemoteRegisteredIterator is returned from FilterRemoteRegistered and is used to iterate over the raw logs and unpacked data for RemoteRegistered events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableRemoteRegisteredIterator struct { + Event *ERC20TokenHomeUpgradeableRemoteRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableRemoteRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableRemoteRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableRemoteRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableRemoteRegistered represents a RemoteRegistered event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableRemoteRegistered struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + InitialCollateralNeeded *big.Int + TokenDecimals uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemoteRegistered is a free log retrieval operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterRemoteRegistered(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*ERC20TokenHomeUpgradeableRemoteRegisteredIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableRemoteRegisteredIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "RemoteRegistered", logs: logs, sub: sub}, nil +} + +// WatchRemoteRegistered is a free log subscription operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchRemoteRegistered(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableRemoteRegistered, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableRemoteRegistered) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "RemoteRegistered", 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 +} + +// ParseRemoteRegistered is a log parse operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseRemoteRegistered(log types.Log) (*ERC20TokenHomeUpgradeableRemoteRegistered, error) { + event := new(ERC20TokenHomeUpgradeableRemoteRegistered) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "RemoteRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTeleporterAddressPausedIterator struct { + Event *ERC20TokenHomeUpgradeableTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenHomeUpgradeableTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTeleporterAddressPausedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableTeleporterAddressPaused) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseTeleporterAddressPaused(log types.Log) (*ERC20TokenHomeUpgradeableTeleporterAddressPaused, error) { + event := new(ERC20TokenHomeUpgradeableTeleporterAddressPaused) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTeleporterAddressUnpausedIterator struct { + Event *ERC20TokenHomeUpgradeableTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenHomeUpgradeableTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTeleporterAddressUnpausedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableTeleporterAddressUnpaused) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*ERC20TokenHomeUpgradeableTeleporterAddressUnpaused, error) { + event := new(ERC20TokenHomeUpgradeableTeleporterAddressUnpaused) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableTokensAndCallRoutedIterator is returned from FilterTokensAndCallRouted and is used to iterate over the raw logs and unpacked data for TokensAndCallRouted events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensAndCallRoutedIterator struct { + Event *ERC20TokenHomeUpgradeableTokensAndCallRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableTokensAndCallRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableTokensAndCallRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableTokensAndCallRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableTokensAndCallRouted represents a TokensAndCallRouted event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensAndCallRouted struct { + TeleporterMessageID [32]byte + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallRouted is a free log retrieval operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterTokensAndCallRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*ERC20TokenHomeUpgradeableTokensAndCallRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTokensAndCallRoutedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "TokensAndCallRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallRouted is a free log subscription operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchTokensAndCallRouted(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableTokensAndCallRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableTokensAndCallRouted) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallRouted", 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 +} + +// ParseTokensAndCallRouted is a log parse operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseTokensAndCallRouted(log types.Log) (*ERC20TokenHomeUpgradeableTokensAndCallRouted, error) { + event := new(ERC20TokenHomeUpgradeableTokensAndCallRouted) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensAndCallSentIterator struct { + Event *ERC20TokenHomeUpgradeableTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableTokensAndCallSent represents a TokensAndCallSent event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenHomeUpgradeableTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTokensAndCallSentIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableTokensAndCallSent) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseTokensAndCallSent(log types.Log) (*ERC20TokenHomeUpgradeableTokensAndCallSent, error) { + event := new(ERC20TokenHomeUpgradeableTokensAndCallSent) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableTokensRoutedIterator is returned from FilterTokensRouted and is used to iterate over the raw logs and unpacked data for TokensRouted events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensRoutedIterator struct { + Event *ERC20TokenHomeUpgradeableTokensRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableTokensRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableTokensRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableTokensRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableTokensRouted represents a TokensRouted event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensRouted struct { + TeleporterMessageID [32]byte + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensRouted is a free log retrieval operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterTokensRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*ERC20TokenHomeUpgradeableTokensRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTokensRoutedIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "TokensRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensRouted is a free log subscription operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchTokensRouted(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableTokensRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableTokensRouted) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensRouted", 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 +} + +// ParseTokensRouted is a log parse operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseTokensRouted(log types.Log) (*ERC20TokenHomeUpgradeableTokensRouted, error) { + event := new(ERC20TokenHomeUpgradeableTokensRouted) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensSentIterator struct { + Event *ERC20TokenHomeUpgradeableTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableTokensSent represents a TokensSent event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenHomeUpgradeableTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTokensSentIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableTokensSent) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseTokensSent(log types.Log) (*ERC20TokenHomeUpgradeableTokensSent, error) { + event := new(ERC20TokenHomeUpgradeableTokensSent) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenHomeUpgradeableTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensWithdrawnIterator struct { + Event *ERC20TokenHomeUpgradeableTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenHomeUpgradeableTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenHomeUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenHomeUpgradeableTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenHomeUpgradeableTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenHomeUpgradeableTokensWithdrawn represents a TokensWithdrawn event raised by the ERC20TokenHomeUpgradeable contract. +type ERC20TokenHomeUpgradeableTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*ERC20TokenHomeUpgradeableTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenHomeUpgradeableTokensWithdrawnIterator{contract: _ERC20TokenHomeUpgradeable.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *ERC20TokenHomeUpgradeableTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenHomeUpgradeable.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenHomeUpgradeableTokensWithdrawn) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenHomeUpgradeable *ERC20TokenHomeUpgradeableFilterer) ParseTokensWithdrawn(log types.Log) (*ERC20TokenHomeUpgradeableTokensWithdrawn, error) { + event := new(ERC20TokenHomeUpgradeableTokensWithdrawn) + if err := _ERC20TokenHomeUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenHome/NativeTokenHome/NativeTokenHome.go b/abi-bindings/go/ictt/TokenHome/NativeTokenHome/NativeTokenHome.go new file mode 100644 index 000000000..5c2347224 --- /dev/null +++ b/abi-bindings/go/ictt/TokenHome/NativeTokenHome/NativeTokenHome.go @@ -0,0 +1,2854 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokenhome + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RemoteTokenTransferrerSettings is an auto generated low-level Go binding around an user-defined struct. +type RemoteTokenTransferrerSettings struct { + Registered bool + CollateralNeeded *big.Int + TokenMultiplier *big.Int + MultiplyOnRemote bool +} + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// NativeTokenHomeMetaData contains all meta data concerning the NativeTokenHome contract. +var NativeTokenHomeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"wrappedTokenAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"CollateralAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialCollateralNeeded\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"RemoteRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"NATIVE_TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"addCollateral\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getRemoteTokenTransferrerSettings\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralNeeded\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"multiplyOnRemote\",\"type\":\"bool\"}],\"internalType\":\"structRemoteTokenTransferrerSettings\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getTransferredBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"wrappedTokenAddress\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561000f575f80fd5b506040516152ae3803806152ae83398101604081905261002e91610890565b61003a84848484610046565b505050506108f1565b50565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f8115801561008f5750825b90505f826001600160401b031660011480156100aa5750303b155b9050811580156100b8575080155b156100d65760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561010457845460ff60401b1916680100000000000000001785555b61011089898989610161565b831561015657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b610169610186565b6101778484848460126101d6565b61018081610202565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff166101d457604051631afcd79f60e31b815260040160405180910390fd5b565b6101de610186565b6101e985858561024b565b6101f161026b565b6101fb828261027b565b5050505050565b61020a610186565b7f3b5030f10c94fcbdaa3022348ff0b82dbd4c0c71339e41ff59d0bdc92179d60080546001600160a01b0319166001600160a01b0392909216919091179055565b610253610186565b61025d8382610407565b6102668261042d565b505050565b610273610186565b6101d461043e565b610283610186565b6001600160a01b0382166102de5760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f20746f6b656e206164647265737300000060448201526064015b60405180910390fd5b60128160ff16111561033d5760405162461bcd60e51b815260206004820152602260248201527f546f6b656e486f6d653a20746f6b656e20646563696d616c7320746f6f2068696044820152610ced60f31b60648201526084016102d5565b5f7f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e60090507302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103b1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103d591906108da565b8155600101805460ff909216600160a01b026001600160a81b03199092166001600160a01b0390931692909217179055565b61040f610186565b610417610468565b61041f610478565b6104298282610480565b5050565b610435610186565b61004381610604565b5f7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c75005b6001905550565b610470610186565b6101d461063e565b6101d4610186565b610488610186565b6001600160a01b0382166105045760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084016102d5565b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610569573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061058d91906108da565b116105e25760405162461bcd60e51b815260206004820152603260248201525f8051602061528e833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016102d5565b81546001600160a01b0319166001600160a01b0382161782556101808361066d565b61060c610186565b6001600160a01b03811661063557604051631e4fbdf760e01b81525f60048201526024016102d5565b61004381610805565b610646610186565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00610461565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa1580156106d4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106f891906108da565b6002830154909150818411156107575760405162461bcd60e51b815260206004820152603160248201525f8051602061528e83398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016102d5565b8084116107cc5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016102d5565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b80516001600160a01b038116811461088b575f80fd5b919050565b5f805f80608085870312156108a3575f80fd5b6108ac85610875565b93506108ba60208601610875565b9250604085015191506108cf60608601610875565b905092959194509250565b5f602082840312156108ea575f80fd5b5051919050565b614990806108fe5f395ff3fe60806040526004361061011e575f3560e01c80638da5cb5b1161009d578063c8511ada11610062578063c8511ada146103c2578063c868efaa146104a2578063d2cc7a70146104c1578063efb5b95e146104f4578063f2fde38b14610514575f80fd5b80638da5cb5b14610305578063909a6ac0146103415780639731429714610361578063b0b78b2614610390578063be203094146103a3575f80fd5b80635eb99514116100e35780635eb995141461028c57806362e3901b146102ab5780636e6eef8d146102cb578063715018a6146102de5780638bf2fa94146102f2575f80fd5b806310fe9ae8146101ac578063154d625a146102015780632b0d8f181461022e5780634213cf781461024d5780634511243e1461026d575f80fd5b366101a8575f805160206148db833981519152546001600160a01b031633146101a65760405162461bcd60e51b815260206004820152602f60248201527f4e6174697665546f6b656e486f6d653a20696e76616c6964207265636569766560448201526e103830bcb0b136329039b2b73232b960891b60648201526084015b60405180910390fd5b005b5f80fd5b3480156101b7575f80fd5b507f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e601546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b34801561020c575f80fd5b5061022061021b3660046139b3565b610533565b6040519081526020016101f8565b348015610239575f80fd5b506101a66102483660046139e1565b61057b565b348015610258575f80fd5b505f805160206148bb83398151915254610220565b348015610278575f80fd5b506101a66102873660046139e1565b610674565b348015610297575f80fd5b506101a66102a63660046139fc565b610763565b3480156102b6575f80fd5b506102205f805160206148bb83398151915281565b6101a66102d9366004613a13565b610777565b3480156102e9575f80fd5b506101a66107a0565b6101a6610300366004613a4a565b6107b3565b348015610310575f80fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03166101e4565b34801561034c575f80fd5b506102205f8051602061493b83398151915281565b34801561036c575f80fd5b5061038061037b3660046139e1565b6107cb565b60405190151581526020016101f8565b6101a661039e3660046139b3565b6107eb565b3480156103ae575f80fd5b506101a66103bd366004613a61565b6107fa565b3480156103cd575f80fd5b5061046b6103dc3660046139b3565b60408051608080820183525f808352602080840182905283850182905260609384018290529581525f805160206148fb83398151915286528381206001600160a01b039590951681529385529282902082519384018352805460ff9081161515855260018201549585019590955260028101549284019290925260039091015490921615159181019190915290565b6040516101f89190815115158152602080830151908201526040808301519082015260609182015115159181019190915260800190565b3480156104ad575f80fd5b506101a66104bc366004613ab1565b61090c565b3480156104cc575f80fd5b507fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0254610220565b3480156104ff575f80fd5b506102205f805160206148db83398151915281565b34801561051f575f80fd5b506101a661052e3660046139e1565b610ac9565b5f8281527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03851684529091529020545b92915050565b5f8051602061493b833981519152610591610b03565b6001600160a01b0382166105b75760405162461bcd60e51b815260040161019d90613b32565b6105c18183610b0b565b156106245760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b606482015260840161019d565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b5f8051602061493b83398151915261068a610b03565b6001600160a01b0382166106b05760405162461bcd60e51b815260040161019d90613b32565b6106ba8183610b0b565b6107185760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b606482015260840161019d565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b61076b610b03565b61077481610b2c565b50565b61077461078f5f805160206148bb8339815191525490565b303361079a85613caa565b34610cc4565b6107a8610f27565b6107b15f610f82565b565b6107746107c536839003830183613d78565b34610ff2565b5f5f8051602061493b8339815191526107e48184610b0b565b9392505050565b6107f68282346111ac565b5050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561083e5750825b90505f826001600160401b031660011480156108595750303b155b905081158015610867575080155b156108855760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108af57845460ff60401b1916600160401b1785555b6108bb8989898961139c565b831561090157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6109146113bb565b5f5f8051602061493b83398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561097f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a39190613e02565b1015610a0a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b606482015260840161019d565b610a148133610b0b565b15610a7a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b606482015260840161019d565b610aba858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061140592505050565b50610ac36117f9565b50505050565b610ad1610f27565b6001600160a01b038116610afa57604051631e4fbdf760e01b81525f600482015260240161019d565b61077481610f82565b6107b1610f27565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b5f8051602061493b83398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610b80573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ba49190613e02565b600283015490915081841115610c165760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b606482015260840161019d565b808411610c8b5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e00606482015260840161019d565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b5f8051602061491b8339815191528054600114610cf35760405162461bcd60e51b815260040161019d90613e19565b60028155610d0083611823565b60c08301516001600160a01b031615610d2b5760405162461bcd60e51b815260040161019d90613e5d565b5f80610d4b855f0151866020015186886101000151896101200151611a08565b915091505f604051806040016040528060026004811115610d6e57610d6e613ea3565b81526020016040518061010001604052808c81526020018b6001600160a01b031681526020018a6001600160a01b0316815260200189604001516001600160a01b03168152602001868152602001896060015181526020018960a0015181526020018960e001516001600160a01b0316815250604051602001610df19190613f04565b60405160208183030381529060405281525090505f610ed16040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b61010001516001600160a01b03168152602001878152508152602001896080015181526020015f6001600160401b03811115610e7a57610e7a613b80565b604051908082528060200260200182016040528015610ea3578160200160208202803683370190505b50815260200184604051602001610eba9190613fa2565b604051602081830303815290604052815250611bcd565b9050876001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168987604051610f0f929190613fe4565b60405180910390a35050600190925550505050505050565b33610f597f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146107b15760405163118cdaa760e01b815233600482015260240161019d565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f8051602061491b83398151915280546001146110215760405162461bcd60e51b815260040161019d90613e19565b6002815561102e83611ce8565b60e08301516001600160a01b0316156110595760405162461bcd60e51b815260040161019d90613e5d565b5f80611077855f015186602001518688606001518960800151611a08565b915091505f60405180604001604052806001600481111561109a5761109a613ea3565b8152602001604051806040016040528089604001516001600160a01b03168152602001868152506040516020016110d191906140c6565b60405160208183030381529060405281525090505f6111596040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b606001516001600160a01b031681526020018781525081526020018960c0015181526020015f6001600160401b03811115610e7a57610e7a613b80565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb5289876040516111979291906140e6565b60405180910390a35050600190925550505050565b5f8051602061491b83398151915280546001146111db5760405162461bcd60e51b815260040161019d90613e19565b60028082555f8581525f805160206148fb833981519152602090815260408083206001600160a01b03881684528252918290208251608081018452815460ff9081161515808352600184015494830194909452948201549381019390935260030154909216151560608201525f805160206148bb833981519152916112725760405162461bcd60e51b815260040161019d90614167565b5f8160200151116112cf5760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20636f6c6c61746572616c206e656564656044820152601960fa1b606482015260840161019d565b6112d884611d91565b93505f80826020015186106113075760208301515f92506112f990876141b0565b90508260200151955061131a565b85836020015161131791906141b0565b91505b5f88815260028501602090815260408083206001600160a01b038b168085529083529281902060010185905580518981529182018590528a917f6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6910160405180910390a3801561138e5761138e3382611db7565b505060019092555050505050565b6113a4611e75565b6113b2848484846012611ebe565b610ac381611ee3565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008054600119016113ff57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f5f805160206148bb83398151915290505f8280602001905181019061142b9190614205565b905060018151600481111561144257611442613ea3565b0361148a575f8160200151806020019051810190611460919061428d565b90505f61147287878460200151611f19565b9050611481825f015182611db7565b50505050505050565b60028151600481111561149f5761149f613ea3565b036115b8575f81602001518060200190518101906114bd91906142c5565b90505f6114cf87878460800151611f19565b825190915087146115355760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a206d69736d61746368656420736f7572636520626c6f60448201526918dad8da185a5b88125160b21b606482015260840161019d565b856001600160a01b031682602001516001600160a01b0316146115ae5760405162461bcd60e51b815260206004820152602b60248201527f546f6b656e486f6d653a206d69736d617463686564206f726967696e2073656e60448201526a646572206164647265737360a81b606482015260840161019d565b6114818282611fa4565b6003815160048111156115cd576115cd613ea3565b036116a1575f81602001518060200190518101906115eb919061438f565b90505f8061160388888560600151866080015161212a565b91509150611697604051806101000160405280855f0151815260200185602001516001600160a01b0316815260200185604001516001600160a01b03168152602001876001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018381526020015f81526020018560a0015181526020018560c001516001600160a01b0316815250836121d5565b5050505050505050565b6004815160048111156116b6576116b6613ea3565b036117b1575f81602001518060200190518101906116d49190614428565b90505f806116ed8888856080015186610140015161212a565b915091506116978888855f01516040518061016001604052808860200151815260200188604001516001600160a01b0316815260200188606001516001600160a01b031681526020018860a00151815260200188610100015181526020018860c0015181526020018861012001516001600160a01b031681526020018860e001516001600160a01b031681526020018a6001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018681526020015f81525086612360565b5f815160048111156117c5576117c5613ea3565b036117f2575f81602001518060200190518101906117e39190614530565b90506117f086868361253d565b505b5050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b60408101516001600160a01b03166118905760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420636f6e7472616044820152696374206164647265737360b01b606482015260840161019d565b5f8160800151116118b35760405162461bcd60e51b815260040161019d90614592565b5f8160a00151116119125760405162461bcd60e51b815260206004820152602360248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420676173206c696044820152621b5a5d60ea1b606482015260840161019d565b80608001518160a00151106119785760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420726563697069656e7420676173604482015265081b1a5b5a5d60d21b606482015260840161019d565b60e08101516001600160a01b03166119e55760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f2066616c6c6261636b20726563697069656044820152696e74206164647265737360b01b606482015260840161019d565b610140810151156107745760405162461bcd60e51b815260040161019d906145d4565b5f8581525f805160206148fb833981519152602090815260408083206001600160a01b038816845282528083208151608081018352815460ff90811615158083526001840154958301959095526002830154938201939093526003909101549091161515606082015282915f805160206148bb8339815191529190611a9f5760405162461bcd60e51b815260040161019d90614167565b602081015115611b015760405162461bcd60e51b815260206004820152602760248201527f546f6b656e486f6d653a20636f6c6c61746572616c206e656564656420666f726044820152662072656d6f746560c81b606482015260840161019d565b611b0a87611d91565b96508415611b2057611b1d863387612944565b94505b5f611b34826040015183606001518a612a9d565b90505f8111611b855760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f207363616c656420616d6f756e74000000604482015260640161019d565b5f8a815260038401602090815260408083206001600160a01b038d16845290915281208054839290611bb8908490614615565b90915550909a95995094975050505050505050565b5f80611bd7612ab3565b60408401516020015190915015611c7c576040830151516001600160a01b0316611c595760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b606482015260840161019d565b604083015160208101519051611c7c916001600160a01b03909116908390612ba3565b604051630624488560e41b81526001600160a01b03821690636244885090611ca8908690600401614628565b6020604051808303815f875af1158015611cc4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107e49190613e02565b60408101516001600160a01b0316611d4c5760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20726563697069656e74206164647265736044820152607360f81b606482015260840161019d565b5f8160c0015111611d6f5760405162461bcd60e51b815260040161019d90614592565b60a0810151156107745760405162461bcd60e51b815260040161019d906145d4565b5f805160206148db83398151915280545f91906107e4906001600160a01b031684612c2a565b6040518181525f805160206148db833981519152906001600160a01b038416907f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b9060200160405180910390a28054604051632e1a7d4d60e01b8152600481018490526001600160a01b0390911690632e1a7d4d906024015f604051808303815f87803b158015611e46575f80fd5b505af1158015611e58573d5f803e3d5ffd5b50611e70925050506001600160a01b03841683612dcf565b505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166107b157604051631afcd79f60e31b815260040160405180910390fd5b611ec6611e75565b611ed1858585612e62565b611ed9612e7d565b6117f28282612e8d565b611eeb611e75565b5f805160206148db83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b5f8381525f805160206148fb833981519152602090815260408083206001600160a01b038616845282528083208151608081018352815460ff9081161515825260018301549482019490945260028201549281019290925260030154909116151560608201525f805160206148bb83398151915290611f9a81878787612ff4565b9695505050505050565b5f5f805160206148db8339815191528054604051632e1a7d4d60e01b8152600481018590529192506001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015611ff6575f80fd5b505af1158015612008573d5f803e3d5ffd5b50508451602086015160408088015160a089015191515f965061203195509091906024016146df565b60408051601f198184030181529190526020810180516001600160e01b031663161b12ff60e11b17905260c085015160608601519192505f9161207791908690856130e2565b905080156120cb5784606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4856040516120be91815260200190565b60405180910390a26117f2565b84606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb08560405161210a91815260200190565b60405180910390a260e08501516117f2906001600160a01b031685612dcf565b5f8481525f805160206148fb833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff90811615158252600183015494820194909452600282015492810192909252600301549091161515606082015281905f805160206148bb83398151915290826121ae828a8a8a612ff4565b90505f6121c483604001518460600151896131b2565b919a91995090975050505050505050565b5f8051602061491b83398151915280546001146122045760405162461bcd60e51b815260040161019d90613e19565b6002815561221183611ce8565b5f612229845f015185602001518587608001516131bf565b9050805f03612246576122408460e0015184611db7565b50612358565b604080518082019091525f908060018152602001604051806040016040528088604001516001600160a01b031681526020018581525060405160200161228c91906140c6565b60405160208183030381529060405281525090505f6123186040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a606001516001600160a01b031681526020018a6080015181525081526020018860c0015181526020015f6001600160401b03811115610e7a57610e7a613b80565b9050807f825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0878560405161234c9291906140e6565b60405180910390a25050505b600190555050565b5f8051602061491b833981519152805460011461238f5760405162461bcd60e51b815260040161019d90613e19565b6002815561239c83611823565b5f6123b5845f01518560200151858761012001516131bf565b9050805f036123d2576123cc8460c0015184611db7565b50612532565b604080518082019091525f9080600281526020016040518061010001604052808b81526020018a6001600160a01b03168152602001896001600160a01b0316815260200188604001516001600160a01b03168152602001858152602001886060015181526020018860a0015181526020018860e001516001600160a01b03168152506040516020016124649190613f04565b60405160208183030381529060405281525090505f6124f26040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a61010001516001600160a01b031681526020018a61012001518152508152602001886080015181526020015f6001600160401b03811115610e7a57610e7a613b80565b9050807f42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb308785604051612526929190613fe4565b60405180910390a25050505b600190555050505050565b5f805160206148bb833981519152836125a45760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a207a65726f2072656d6f746520626c6f636b636861696044820152631b88125160e21b606482015260840161019d565b8054840361260c5760405162461bcd60e51b815260206004820152602f60248201527f546f6b656e486f6d653a2063616e6e6f742072656769737465722072656d6f7460448201526e329037b71039b0b6b29031b430b4b760891b606482015260840161019d565b6001600160a01b03831661267b5760405162461bcd60e51b815260206004820152603060248201527f546f6b656e486f6d653a207a65726f2072656d6f746520746f6b656e2074726160448201526f6e73666572726572206164647265737360801b606482015260840161019d565b5f84815260028201602090815260408083206001600160a01b038716845290915290205460ff16156126fb5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f746520616c726561647920726567697374604482015263195c995960e21b606482015260840161019d565b6012826040015160ff1611156127655760405162461bcd60e51b815260206004820152602960248201527f546f6b656e486f6d653a2072656d6f746520746f6b656e20646563696d616c73604482015268040e8dede40d0d2ced60bb1b606482015260840161019d565b6001810154602083015160ff908116600160a01b90920416146127d95760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420686f6d6520746f6b656e20646560448201526563696d616c7360d01b606482015260840161019d565b5f806127fa8360010160149054906101000a900460ff168560400151613330565b915091505f61280d8383875f01516131b2565b905081801561282757508451612824908490614724565b15155b1561283a57612837600182614615565b90505b6040518060800160405280600115158152602001828152602001848152602001831515815250846002015f8981526020019081526020015f205f886001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003015f6101000a81548160ff021916908315150217905550905050856001600160a01b0316877ff229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b9083886040015160405161293392919091825260ff16602082015260400190565b60405180910390a350505050505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa15801561298a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129ae9190613e02565b90506129c56001600160a01b038616853086613378565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612a09573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a2d9190613e02565b9050818111612a935760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840161019d565b611f9a82826141b0565b5f612aab84848460016133df565b949350505050565b5f8051602061493b83398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612b0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b319190614737565b9050612b3d8282610b0b565b156105755760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b606482015260840161019d565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612bf0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c149190613e02565b9050610ac38484612c258585614615565b613406565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa158015612c70573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c949190613e02565b9050836001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004015f604051808303818588803b158015612ccf575f80fd5b505af1158015612ce1573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201525f93506001600160a01b03881692506370a082319150602401602060405180830381865afa158015612d2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d4e9190613e02565b9050818111612dbc5760405162461bcd60e51b815260206004820152603460248201527f53616665577261707065644e6174697665546f6b656e4465706f7369743a2062604482015273185b185b98d9481b9bdd081a5b98dc99585cd95960621b606482015260840161019d565b612dc682826141b0565b95945050505050565b80471015612df25760405163cd78605960e01b815230600482015260240161019d565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114612e3b576040519150601f19603f3d011682016040523d82523d5f602084013e612e40565b606091505b5050905080611e7057604051630a12f52160e11b815260040160405180910390fd5b612e6a611e75565b612e748382613495565b611e70826134b7565b612e85611e75565b6107b16134c8565b612e95611e75565b6001600160a01b038216612eeb5760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f20746f6b656e2061646472657373000000604482015260640161019d565b60128160ff161115612f4a5760405162461bcd60e51b815260206004820152602260248201527f546f6b656e486f6d653a20746f6b656e20646563696d616c7320746f6f2068696044820152610ced60f31b606482015260840161019d565b5f5f805160206148bb83398151915290506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f9e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fc29190613e02565b8155600101805460ff909216600160a01b026001600160a81b03199092166001600160a01b0390931692909217179055565b83515f906130145760405162461bcd60e51b815260040161019d90614167565b6020850151156130725760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f7465206e6f7420636f6c6c61746572616c6044820152631a5e995960e21b606482015260840161019d565b61307d8484846134dc565b5f61309186604001518760600151856131b2565b90505f8111612dc65760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e486f6d653a207a65726f20746f6b656e20616d6f756e7400000000604482015260640161019d565b5f845a10156131335760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e74206761730000000000604482015260640161019d565b834710156131835760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c7565000000604482015260640161019d565b826001600160a01b03163b5f0361319b57505f612aab565b5f805f84516020860188888bf19695505050505050565b5f612aab8484845f6133df565b5f8481525f805160206148fb833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff9081161580158352600184015495830195909552600283015493820193909352600390910154909116151560608201525f805160206148bb833981519152918061324557505f8160200151115b15613254575f92505050612aab565b8385116132b85760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e486f6d653a20696e73756666696369656e7420616d6f756e74207460448201526b6f20636f766572206665657360a01b606482015260840161019d565b6132c284866141b0565b94505f6132d88260400151836060015188612a9d565b9050805f036132ec575f9350505050612aab565b5f88815260038401602090815260408083206001600160a01b038b1684529091528120805483929061331f908490614615565b909155509098975050505050505050565b5f8060ff8085169084161181816133535761334b8587614752565b60ff16613361565b61335d8686614752565b60ff165b61336c90600a61484b565b96919550909350505050565b6040516001600160a01b038481166024830152838116604483015260648201839052610ac39186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506135c9565b5f811515841515036133fc576133f58584614856565b9050612aab565b612dc6858461486d565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052613457848261362a565b610ac3576040516001600160a01b0384811660248301525f604483015261348b91869182169063095ea7b3906064016133ad565b610ac384826135c9565b61349d611e75565b6134a56136c7565b6134ad6136d7565b6107f682826136df565b6134bf611e75565b61077481613863565b5f5f8051602061491b83398151915261181c565b5f8381527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03861684529091529020545f805160206148bb83398151915290828110156135935760405162461bcd60e51b815260206004820152602e60248201527f546f6b656e486f6d653a20696e73756666696369656e7420746f6b656e20747260448201526d616e736665722062616c616e636560901b606482015260840161019d565b61359d83826141b0565b5f9586526003909201602090815260408087206001600160a01b03909616875294905250919092205550565b5f6135dd6001600160a01b0384168361386b565b905080515f141580156136015750808060200190518101906135ff9190614880565b155b15611e7057604051635274afe760e01b81526001600160a01b038416600482015260240161019d565b5f805f846001600160a01b031684604051613645919061489f565b5f604051808303815f865af19150503d805f811461367e576040519150601f19603f3d011682016040523d82523d5f602084013e613683565b606091505b50915091508180156136ad5750805115806136ad5750808060200190518101906136ad9190614880565b8015612dc65750505050506001600160a01b03163b151590565b6136cf611e75565b6107b1613878565b6107b1611e75565b6136e7611e75565b6001600160a01b0382166137635760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840161019d565b5f5f8051602061493b83398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137b5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137d99190613e02565b116138415760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b606482015260840161019d565b81546001600160a01b0319166001600160a01b038216178255610ac383610b2c565b610ad1611e75565b60606107e483835f613880565b6117f9611e75565b6060814710156138a55760405163cd78605960e01b815230600482015260240161019d565b5f80856001600160a01b031684866040516138c0919061489f565b5f6040518083038185875af1925050503d805f81146138fa576040519150601f19603f3d011682016040523d82523d5f602084013e6138ff565b606091505b5091509150611f9a86838360608261391f5761391a82613966565b6107e4565b815115801561393657506001600160a01b0384163b155b1561395f57604051639996b31560e01b81526001600160a01b038516600482015260240161019d565b50806107e4565b8051156139765780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610774575f80fd5b80356139ae8161398f565b919050565b5f80604083850312156139c4575f80fd5b8235915060208301356139d68161398f565b809150509250929050565b5f602082840312156139f1575f80fd5b81356107e48161398f565b5f60208284031215613a0c575f80fd5b5035919050565b5f60208284031215613a23575f80fd5b81356001600160401b03811115613a38575f80fd5b820161016081850312156107e4575f80fd5b5f6101008284031215613a5b575f80fd5b50919050565b5f805f8060808587031215613a74575f80fd5b8435613a7f8161398f565b93506020850135613a8f8161398f565b9250604085013591506060850135613aa68161398f565b939692955090935050565b5f805f8060608587031215613ac4575f80fd5b843593506020850135613ad68161398f565b925060408501356001600160401b0380821115613af1575f80fd5b818701915087601f830112613b04575f80fd5b813581811115613b12575f80fd5b886020828501011115613b23575f80fd5b95989497505060200194505050565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b60405161016081016001600160401b0381118282101715613bb757613bb7613b80565b60405290565b60405161010081016001600160401b0381118282101715613bb757613bb7613b80565b604080519081016001600160401b0381118282101715613bb757613bb7613b80565b604051601f8201601f191681016001600160401b0381118282101715613c2a57613c2a613b80565b604052919050565b5f6001600160401b03821115613c4a57613c4a613b80565b50601f01601f191660200190565b5f82601f830112613c67575f80fd5b8135613c7a613c7582613c32565b613c02565b818152846020838601011115613c8e575f80fd5b816020850160208301375f918101602001919091529392505050565b5f6101608236031215613cbb575f80fd5b613cc3613b94565b82358152613cd3602084016139a3565b6020820152613ce4604084016139a3565b604082015260608301356001600160401b03811115613d01575f80fd5b613d0d36828601613c58565b6060830152506080830135608082015260a083013560a0820152613d3360c084016139a3565b60c0820152613d4460e084016139a3565b60e0820152610100613d578185016139a3565b90820152610120838101359082015261014092830135928101929092525090565b5f6101008284031215613d89575f80fd5b613d91613bbd565b823581526020830135613da38161398f565b60208201526040830135613db68161398f565b6040820152613dc7606084016139a3565b60608201526080830135608082015260a083013560a082015260c083013560c0820152613df660e084016139a3565b60e08201529392505050565b5f60208284031215613e12575f80fd5b5051919050565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b60208082526026908201527f546f6b656e486f6d653a206e6f6e2d7a65726f206d756c74692d686f702066616040820152656c6c6261636b60d01b606082015260800190565b634e487b7160e01b5f52602160045260245ffd5b5f5b83811015613ed1578181015183820152602001613eb9565b50505f910152565b5f8151808452613ef0816020860160208601613eb7565b601f01601f19169290920160200192915050565b60208152815160208201525f602083015160018060a01b03808216604085015280604086015116606085015250506060830151613f4c60808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c0850152613f73610120850183613ed9565b915060c085015160e085015260e0850151613f98828601826001600160a01b03169052565b5090949350505050565b602081525f825160058110613fc557634e487b7160e01b5f52602160045260245ffd5b806020840152506020830151604080840152612aab6060840182613ed9565b60408152825160408201525f602084015161400a60608401826001600160a01b03169052565b5060408401516001600160a01b03166080830152606084015161016060a0840181905261403b6101a0850183613ed9565b9150608086015160c085015260a086015160e085015260c086015161010061406d818701836001600160a01b03169052565b60e0880151915061012061408b818801846001600160a01b03169052565b908801519150610140906140a9878301846001600160a01b03169052565b880151928601929092525090940151610180830152506020015290565b81516001600160a01b031681526020808301519082015260408101610575565b5f6101208201905083518252602084015160018060a01b03808216602085015280604087015116604085015280606087015116606085015250506080840151608083015260a084015160a083015260c084015160c083015260e084015161415860e08401826001600160a01b03169052565b50826101008301529392505050565b6020808252818101527f546f6b656e486f6d653a2072656d6f7465206e6f742072656769737465726564604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b818103818111156105755761057561419c565b5f82601f8301126141d2575f80fd5b81516141e0613c7582613c32565b8181528460208386010111156141f4575f80fd5b612aab826020830160208701613eb7565b5f60208284031215614215575f80fd5b81516001600160401b038082111561422b575f80fd5b908301906040828603121561423e575f80fd5b614246613be0565b825160058110614254575f80fd5b8152602083015182811115614267575f80fd5b614273878286016141c3565b60208301525095945050505050565b80516139ae8161398f565b5f6040828403121561429d575f80fd5b6142a5613be0565b82516142b08161398f565b81526020928301519281019290925250919050565b5f602082840312156142d5575f80fd5b81516001600160401b03808211156142eb575f80fd5b9083019061010082860312156142ff575f80fd5b614307613bbd565b8251815261431760208401614282565b602082015261432860408401614282565b604082015261433960608401614282565b60608201526080830151608082015260a083015182811115614359575f80fd5b614365878286016141c3565b60a08301525060c083015160c082015261438160e08401614282565b60e082015295945050505050565b5f60e0828403121561439f575f80fd5b60405160e081018181106001600160401b03821117156143c1576143c1613b80565b6040528251815260208301516143d68161398f565b602082015260408301516143e98161398f565b80604083015250606083015160608201526080830151608082015260a083015160a082015260c083015161441c8161398f565b60c08201529392505050565b5f60208284031215614438575f80fd5b81516001600160401b038082111561444e575f80fd5b908301906101608286031215614462575f80fd5b61446a613b94565b61447383614282565b81526020830151602082015261448b60408401614282565b604082015261449c60608401614282565b60608201526080830151608082015260a0830151828111156144bc575f80fd5b6144c8878286016141c3565b60a08301525060c083015160c08201526144e460e08401614282565b60e082015261010083810151908201526101209150614504828401614282565b9181019190915261014091820151918101919091529392505050565b805160ff811681146139ae575f80fd5b5f60608284031215614540575f80fd5b604051606081018181106001600160401b038211171561456257614562613b80565b6040528251815261457560208401614520565b602082015261458660408401614520565b60408201529392505050565b60208082526022908201527f546f6b656e486f6d653a207a65726f20726571756972656420676173206c696d6040820152611a5d60f21b606082015260800190565b60208082526021908201527f546f6b656e486f6d653a206e6f6e2d7a65726f207365636f6e646172792066656040820152606560f81b606082015260800190565b808201808211156105755761057561419c565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b808410156146b557845183168252938501936001939093019290850190614693565b5060a0880151878203601f190160e089015294506146d38186613ed9565b98975050505050505050565b8481526001600160a01b038481166020830152831660408201526080606082018190525f90611f9a90830184613ed9565b634e487b7160e01b5f52601260045260245ffd5b5f8261473257614732614710565b500690565b5f60208284031215614747575f80fd5b81516107e48161398f565b60ff82811682821603908111156105755761057561419c565b600181815b808511156147a557815f190482111561478b5761478b61419c565b8085161561479857918102915b93841c9390800290614770565b509250929050565b5f826147bb57506001610575565b816147c757505f610575565b81600181146147dd57600281146147e757614803565b6001915050610575565b60ff8411156147f8576147f861419c565b50506001821b610575565b5060208310610133831016604e8410600b8410161715614826575081810a610575565b614830838361476b565b805f19048211156148435761484361419c565b029392505050565b5f6107e483836147ad565b80820281158282048414176105755761057561419c565b5f8261487b5761487b614710565b500490565b5f60208284031215614890575f80fd5b815180151581146107e4575f80fd5b5f82516148b0818460208701613eb7565b919091019291505056fe9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e6003b5030f10c94fcbdaa3022348ff0b82dbd4c0c71339e41ff59d0bdc92179d6009316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e602d2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a2646970667358221220061e742b5c1f9766bd5aa698c4c83fbe221de1a119c477e3b444d1aabeede77964736f6c6343000819003354656c65706f7274657252656769737472794170703a20696e76616c69642054", +} + +// NativeTokenHomeABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenHomeMetaData.ABI instead. +var NativeTokenHomeABI = NativeTokenHomeMetaData.ABI + +// NativeTokenHomeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenHomeMetaData.Bin instead. +var NativeTokenHomeBin = NativeTokenHomeMetaData.Bin + +// DeployNativeTokenHome deploys a new Ethereum contract, binding an instance of NativeTokenHome to it. +func DeployNativeTokenHome(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, wrappedTokenAddress common.Address) (common.Address, *types.Transaction, *NativeTokenHome, error) { + parsed, err := NativeTokenHomeMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NativeTokenHomeBin), backend, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenHome{NativeTokenHomeCaller: NativeTokenHomeCaller{contract: contract}, NativeTokenHomeTransactor: NativeTokenHomeTransactor{contract: contract}, NativeTokenHomeFilterer: NativeTokenHomeFilterer{contract: contract}}, nil +} + +// NativeTokenHome is an auto generated Go binding around an Ethereum contract. +type NativeTokenHome struct { + NativeTokenHomeCaller // Read-only binding to the contract + NativeTokenHomeTransactor // Write-only binding to the contract + NativeTokenHomeFilterer // Log filterer for contract events +} + +// NativeTokenHomeCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenHomeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenHomeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenHomeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenHomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenHomeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenHomeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenHomeSession struct { + Contract *NativeTokenHome // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenHomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenHomeCallerSession struct { + Contract *NativeTokenHomeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenHomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenHomeTransactorSession struct { + Contract *NativeTokenHomeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenHomeRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenHomeRaw struct { + Contract *NativeTokenHome // Generic contract binding to access the raw methods on +} + +// NativeTokenHomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenHomeCallerRaw struct { + Contract *NativeTokenHomeCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenHomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenHomeTransactorRaw struct { + Contract *NativeTokenHomeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenHome creates a new instance of NativeTokenHome, bound to a specific deployed contract. +func NewNativeTokenHome(address common.Address, backend bind.ContractBackend) (*NativeTokenHome, error) { + contract, err := bindNativeTokenHome(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenHome{NativeTokenHomeCaller: NativeTokenHomeCaller{contract: contract}, NativeTokenHomeTransactor: NativeTokenHomeTransactor{contract: contract}, NativeTokenHomeFilterer: NativeTokenHomeFilterer{contract: contract}}, nil +} + +// NewNativeTokenHomeCaller creates a new read-only instance of NativeTokenHome, bound to a specific deployed contract. +func NewNativeTokenHomeCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenHomeCaller, error) { + contract, err := bindNativeTokenHome(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenHomeCaller{contract: contract}, nil +} + +// NewNativeTokenHomeTransactor creates a new write-only instance of NativeTokenHome, bound to a specific deployed contract. +func NewNativeTokenHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenHomeTransactor, error) { + contract, err := bindNativeTokenHome(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenHomeTransactor{contract: contract}, nil +} + +// NewNativeTokenHomeFilterer creates a new log filterer instance of NativeTokenHome, bound to a specific deployed contract. +func NewNativeTokenHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenHomeFilterer, error) { + contract, err := bindNativeTokenHome(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenHomeFilterer{contract: contract}, nil +} + +// bindNativeTokenHome binds a generic wrapper to an already deployed contract. +func bindNativeTokenHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenHomeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenHome *NativeTokenHomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenHome.Contract.NativeTokenHomeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenHome *NativeTokenHomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHome.Contract.NativeTokenHomeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenHome *NativeTokenHomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenHome.Contract.NativeTokenHomeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenHome *NativeTokenHomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenHome.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenHome *NativeTokenHomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHome.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenHome *NativeTokenHomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenHome.Contract.contract.Transact(opts, method, params...) +} + +// NATIVETOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0xefb5b95e. +// +// Solidity: function NATIVE_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCaller) NATIVETOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "NATIVE_TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// NATIVETOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0xefb5b95e. +// +// Solidity: function NATIVE_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeSession) NATIVETOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHome.Contract.NATIVETOKENHOMESTORAGELOCATION(&_NativeTokenHome.CallOpts) +} + +// NATIVETOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0xefb5b95e. +// +// Solidity: function NATIVE_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCallerSession) NATIVETOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHome.Contract.NATIVETOKENHOMESTORAGELOCATION(&_NativeTokenHome.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHome.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenHome.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHome.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenHome.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCaller) TOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHome.Contract.TOKENHOMESTORAGELOCATION(&_NativeTokenHome.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCallerSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHome.Contract.TOKENHOMESTORAGELOCATION(&_NativeTokenHome.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenHome.Contract.GetBlockchainID(&_NativeTokenHome.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenHome *NativeTokenHomeCallerSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenHome.Contract.GetBlockchainID(&_NativeTokenHome.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenHome *NativeTokenHomeCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenHome *NativeTokenHomeSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenHome.Contract.GetMinTeleporterVersion(&_NativeTokenHome.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenHome *NativeTokenHomeCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenHome.Contract.GetMinTeleporterVersion(&_NativeTokenHome.CallOpts) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_NativeTokenHome *NativeTokenHomeCaller) GetRemoteTokenTransferrerSettings(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "getRemoteTokenTransferrerSettings", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(RemoteTokenTransferrerSettings), err + } + + out0 := *abi.ConvertType(out[0], new(RemoteTokenTransferrerSettings)).(*RemoteTokenTransferrerSettings) + + return out0, err + +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_NativeTokenHome *NativeTokenHomeSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _NativeTokenHome.Contract.GetRemoteTokenTransferrerSettings(&_NativeTokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_NativeTokenHome *NativeTokenHomeCallerSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _NativeTokenHome.Contract.GetRemoteTokenTransferrerSettings(&_NativeTokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_NativeTokenHome *NativeTokenHomeCaller) GetTokenAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "getTokenAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_NativeTokenHome *NativeTokenHomeSession) GetTokenAddress() (common.Address, error) { + return _NativeTokenHome.Contract.GetTokenAddress(&_NativeTokenHome.CallOpts) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_NativeTokenHome *NativeTokenHomeCallerSession) GetTokenAddress() (common.Address, error) { + return _NativeTokenHome.Contract.GetTokenAddress(&_NativeTokenHome.CallOpts) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_NativeTokenHome *NativeTokenHomeCaller) GetTransferredBalance(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "getTransferredBalance", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_NativeTokenHome *NativeTokenHomeSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _NativeTokenHome.Contract.GetTransferredBalance(&_NativeTokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_NativeTokenHome *NativeTokenHomeCallerSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _NativeTokenHome.Contract.GetTransferredBalance(&_NativeTokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenHome *NativeTokenHomeCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenHome *NativeTokenHomeSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenHome.Contract.IsTeleporterAddressPaused(&_NativeTokenHome.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenHome *NativeTokenHomeCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenHome.Contract.IsTeleporterAddressPaused(&_NativeTokenHome.CallOpts, teleporterAddress) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenHome *NativeTokenHomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenHome.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenHome *NativeTokenHomeSession) Owner() (common.Address, error) { + return _NativeTokenHome.Contract.Owner(&_NativeTokenHome.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenHome *NativeTokenHomeCallerSession) Owner() (common.Address, error) { + return _NativeTokenHome.Contract.Owner(&_NativeTokenHome.CallOpts) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xb0b78b26. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) AddCollateral(opts *bind.TransactOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "addCollateral", remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xb0b78b26. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) payable returns() +func (_NativeTokenHome *NativeTokenHomeSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.AddCollateral(&_NativeTokenHome.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xb0b78b26. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.AddCollateral(&_NativeTokenHome.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0xbe203094. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address wrappedTokenAddress) returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) Initialize(opts *bind.TransactOpts, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, wrappedTokenAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "initialize", teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0xbe203094. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address wrappedTokenAddress) returns() +func (_NativeTokenHome *NativeTokenHomeSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, wrappedTokenAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.Initialize(&_NativeTokenHome.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0xbe203094. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address wrappedTokenAddress) returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, wrappedTokenAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.Initialize(&_NativeTokenHome.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHome *NativeTokenHomeSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.PauseTeleporterAddress(&_NativeTokenHome.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.PauseTeleporterAddress(&_NativeTokenHome.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenHome *NativeTokenHomeSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenHome.Contract.ReceiveTeleporterMessage(&_NativeTokenHome.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenHome.Contract.ReceiveTeleporterMessage(&_NativeTokenHome.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenHome *NativeTokenHomeSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenHome.Contract.RenounceOwnership(&_NativeTokenHome.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenHome.Contract.RenounceOwnership(&_NativeTokenHome.TransactOpts) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) Send(opts *bind.TransactOpts, input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "send", input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenHome *NativeTokenHomeSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenHome.Contract.Send(&_NativeTokenHome.TransactOpts, input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenHome.Contract.Send(&_NativeTokenHome.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "sendAndCall", input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenHome *NativeTokenHomeSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenHome.Contract.SendAndCall(&_NativeTokenHome.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenHome.Contract.SendAndCall(&_NativeTokenHome.TransactOpts, input) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenHome *NativeTokenHomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.TransferOwnership(&_NativeTokenHome.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.TransferOwnership(&_NativeTokenHome.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHome *NativeTokenHomeSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.UnpauseTeleporterAddress(&_NativeTokenHome.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHome.Contract.UnpauseTeleporterAddress(&_NativeTokenHome.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _NativeTokenHome.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenHome *NativeTokenHomeSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenHome.Contract.UpdateMinTeleporterVersion(&_NativeTokenHome.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenHome.Contract.UpdateMinTeleporterVersion(&_NativeTokenHome.TransactOpts, version) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHome.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenHome *NativeTokenHomeSession) Receive() (*types.Transaction, error) { + return _NativeTokenHome.Contract.Receive(&_NativeTokenHome.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenHome *NativeTokenHomeTransactorSession) Receive() (*types.Transaction, error) { + return _NativeTokenHome.Contract.Receive(&_NativeTokenHome.TransactOpts) +} + +// NativeTokenHomeCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the NativeTokenHome contract. +type NativeTokenHomeCallFailedIterator struct { + Event *NativeTokenHomeCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeCallFailed represents a CallFailed event raised by the NativeTokenHome contract. +type NativeTokenHomeCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenHomeCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeCallFailedIterator{contract: _NativeTokenHome.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeCallFailed) + if err := _NativeTokenHome.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseCallFailed(log types.Log) (*NativeTokenHomeCallFailed, error) { + event := new(NativeTokenHomeCallFailed) + if err := _NativeTokenHome.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the NativeTokenHome contract. +type NativeTokenHomeCallSucceededIterator struct { + Event *NativeTokenHomeCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeCallSucceeded represents a CallSucceeded event raised by the NativeTokenHome contract. +type NativeTokenHomeCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenHomeCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeCallSucceededIterator{contract: _NativeTokenHome.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeCallSucceeded) + if err := _NativeTokenHome.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseCallSucceeded(log types.Log) (*NativeTokenHomeCallSucceeded, error) { + event := new(NativeTokenHomeCallSucceeded) + if err := _NativeTokenHome.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeCollateralAddedIterator is returned from FilterCollateralAdded and is used to iterate over the raw logs and unpacked data for CollateralAdded events raised by the NativeTokenHome contract. +type NativeTokenHomeCollateralAddedIterator struct { + Event *NativeTokenHomeCollateralAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeCollateralAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeCollateralAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeCollateralAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeCollateralAdded represents a CollateralAdded event raised by the NativeTokenHome contract. +type NativeTokenHomeCollateralAdded struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + Amount *big.Int + Remaining *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollateralAdded is a free log retrieval operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterCollateralAdded(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*NativeTokenHomeCollateralAddedIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeCollateralAddedIterator{contract: _NativeTokenHome.contract, event: "CollateralAdded", logs: logs, sub: sub}, nil +} + +// WatchCollateralAdded is a free log subscription operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchCollateralAdded(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeCollateralAdded, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeCollateralAdded) + if err := _NativeTokenHome.contract.UnpackLog(event, "CollateralAdded", 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 +} + +// ParseCollateralAdded is a log parse operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseCollateralAdded(log types.Log) (*NativeTokenHomeCollateralAdded, error) { + event := new(NativeTokenHomeCollateralAdded) + if err := _NativeTokenHome.contract.UnpackLog(event, "CollateralAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the NativeTokenHome contract. +type NativeTokenHomeInitializedIterator struct { + Event *NativeTokenHomeInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeInitialized represents a Initialized event raised by the NativeTokenHome contract. +type NativeTokenHomeInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*NativeTokenHomeInitializedIterator, error) { + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NativeTokenHomeInitializedIterator{contract: _NativeTokenHome.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeInitialized) (event.Subscription, error) { + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeInitialized) + if err := _NativeTokenHome.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseInitialized(log types.Log) (*NativeTokenHomeInitialized, error) { + event := new(NativeTokenHomeInitialized) + if err := _NativeTokenHome.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the NativeTokenHome contract. +type NativeTokenHomeMinTeleporterVersionUpdatedIterator struct { + Event *NativeTokenHomeMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the NativeTokenHome contract. +type NativeTokenHomeMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*NativeTokenHomeMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeMinTeleporterVersionUpdatedIterator{contract: _NativeTokenHome.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeMinTeleporterVersionUpdated) + if err := _NativeTokenHome.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*NativeTokenHomeMinTeleporterVersionUpdated, error) { + event := new(NativeTokenHomeMinTeleporterVersionUpdated) + if err := _NativeTokenHome.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the NativeTokenHome contract. +type NativeTokenHomeOwnershipTransferredIterator struct { + Event *NativeTokenHomeOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeOwnershipTransferred represents a OwnershipTransferred event raised by the NativeTokenHome contract. +type NativeTokenHomeOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*NativeTokenHomeOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeOwnershipTransferredIterator{contract: _NativeTokenHome.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeOwnershipTransferred) + if err := _NativeTokenHome.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseOwnershipTransferred(log types.Log) (*NativeTokenHomeOwnershipTransferred, error) { + event := new(NativeTokenHomeOwnershipTransferred) + if err := _NativeTokenHome.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeRemoteRegisteredIterator is returned from FilterRemoteRegistered and is used to iterate over the raw logs and unpacked data for RemoteRegistered events raised by the NativeTokenHome contract. +type NativeTokenHomeRemoteRegisteredIterator struct { + Event *NativeTokenHomeRemoteRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeRemoteRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeRemoteRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeRemoteRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeRemoteRegistered represents a RemoteRegistered event raised by the NativeTokenHome contract. +type NativeTokenHomeRemoteRegistered struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + InitialCollateralNeeded *big.Int + TokenDecimals uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemoteRegistered is a free log retrieval operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterRemoteRegistered(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*NativeTokenHomeRemoteRegisteredIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeRemoteRegisteredIterator{contract: _NativeTokenHome.contract, event: "RemoteRegistered", logs: logs, sub: sub}, nil +} + +// WatchRemoteRegistered is a free log subscription operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchRemoteRegistered(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeRemoteRegistered, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeRemoteRegistered) + if err := _NativeTokenHome.contract.UnpackLog(event, "RemoteRegistered", 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 +} + +// ParseRemoteRegistered is a log parse operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseRemoteRegistered(log types.Log) (*NativeTokenHomeRemoteRegistered, error) { + event := new(NativeTokenHomeRemoteRegistered) + if err := _NativeTokenHome.contract.UnpackLog(event, "RemoteRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the NativeTokenHome contract. +type NativeTokenHomeTeleporterAddressPausedIterator struct { + Event *NativeTokenHomeTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the NativeTokenHome contract. +type NativeTokenHomeTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenHomeTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeTeleporterAddressPausedIterator{contract: _NativeTokenHome.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeTeleporterAddressPaused) + if err := _NativeTokenHome.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseTeleporterAddressPaused(log types.Log) (*NativeTokenHomeTeleporterAddressPaused, error) { + event := new(NativeTokenHomeTeleporterAddressPaused) + if err := _NativeTokenHome.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the NativeTokenHome contract. +type NativeTokenHomeTeleporterAddressUnpausedIterator struct { + Event *NativeTokenHomeTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the NativeTokenHome contract. +type NativeTokenHomeTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenHomeTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeTeleporterAddressUnpausedIterator{contract: _NativeTokenHome.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeTeleporterAddressUnpaused) + if err := _NativeTokenHome.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*NativeTokenHomeTeleporterAddressUnpaused, error) { + event := new(NativeTokenHomeTeleporterAddressUnpaused) + if err := _NativeTokenHome.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeTokensAndCallRoutedIterator is returned from FilterTokensAndCallRouted and is used to iterate over the raw logs and unpacked data for TokensAndCallRouted events raised by the NativeTokenHome contract. +type NativeTokenHomeTokensAndCallRoutedIterator struct { + Event *NativeTokenHomeTokensAndCallRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeTokensAndCallRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeTokensAndCallRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeTokensAndCallRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeTokensAndCallRouted represents a TokensAndCallRouted event raised by the NativeTokenHome contract. +type NativeTokenHomeTokensAndCallRouted struct { + TeleporterMessageID [32]byte + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallRouted is a free log retrieval operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterTokensAndCallRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*NativeTokenHomeTokensAndCallRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeTokensAndCallRoutedIterator{contract: _NativeTokenHome.contract, event: "TokensAndCallRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallRouted is a free log subscription operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchTokensAndCallRouted(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeTokensAndCallRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeTokensAndCallRouted) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensAndCallRouted", 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 +} + +// ParseTokensAndCallRouted is a log parse operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseTokensAndCallRouted(log types.Log) (*NativeTokenHomeTokensAndCallRouted, error) { + event := new(NativeTokenHomeTokensAndCallRouted) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensAndCallRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the NativeTokenHome contract. +type NativeTokenHomeTokensAndCallSentIterator struct { + Event *NativeTokenHomeTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeTokensAndCallSent represents a TokensAndCallSent event raised by the NativeTokenHome contract. +type NativeTokenHomeTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenHomeTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeTokensAndCallSentIterator{contract: _NativeTokenHome.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeTokensAndCallSent) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseTokensAndCallSent(log types.Log) (*NativeTokenHomeTokensAndCallSent, error) { + event := new(NativeTokenHomeTokensAndCallSent) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeTokensRoutedIterator is returned from FilterTokensRouted and is used to iterate over the raw logs and unpacked data for TokensRouted events raised by the NativeTokenHome contract. +type NativeTokenHomeTokensRoutedIterator struct { + Event *NativeTokenHomeTokensRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeTokensRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeTokensRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeTokensRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeTokensRouted represents a TokensRouted event raised by the NativeTokenHome contract. +type NativeTokenHomeTokensRouted struct { + TeleporterMessageID [32]byte + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensRouted is a free log retrieval operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterTokensRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*NativeTokenHomeTokensRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeTokensRoutedIterator{contract: _NativeTokenHome.contract, event: "TokensRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensRouted is a free log subscription operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchTokensRouted(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeTokensRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeTokensRouted) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensRouted", 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 +} + +// ParseTokensRouted is a log parse operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseTokensRouted(log types.Log) (*NativeTokenHomeTokensRouted, error) { + event := new(NativeTokenHomeTokensRouted) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the NativeTokenHome contract. +type NativeTokenHomeTokensSentIterator struct { + Event *NativeTokenHomeTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeTokensSent represents a TokensSent event raised by the NativeTokenHome contract. +type NativeTokenHomeTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenHomeTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeTokensSentIterator{contract: _NativeTokenHome.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeTokensSent) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseTokensSent(log types.Log) (*NativeTokenHomeTokensSent, error) { + event := new(NativeTokenHomeTokensSent) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the NativeTokenHome contract. +type NativeTokenHomeTokensWithdrawnIterator struct { + Event *NativeTokenHomeTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeTokensWithdrawn represents a TokensWithdrawn event raised by the NativeTokenHome contract. +type NativeTokenHomeTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*NativeTokenHomeTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenHome.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeTokensWithdrawnIterator{contract: _NativeTokenHome.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenHome.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeTokensWithdrawn) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenHome *NativeTokenHomeFilterer) ParseTokensWithdrawn(log types.Log) (*NativeTokenHomeTokensWithdrawn, error) { + event := new(NativeTokenHomeTokensWithdrawn) + if err := _NativeTokenHome.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenHome/NativeTokenHomeUpgradeable/NativeTokenHomeUpgradeable.go b/abi-bindings/go/ictt/TokenHome/NativeTokenHomeUpgradeable/NativeTokenHomeUpgradeable.go new file mode 100644 index 000000000..db8adb75b --- /dev/null +++ b/abi-bindings/go/ictt/TokenHome/NativeTokenHomeUpgradeable/NativeTokenHomeUpgradeable.go @@ -0,0 +1,2854 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokenhomeupgradeable + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RemoteTokenTransferrerSettings is an auto generated low-level Go binding around an user-defined struct. +type RemoteTokenTransferrerSettings struct { + Registered bool + CollateralNeeded *big.Int + TokenMultiplier *big.Int + MultiplyOnRemote bool +} + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// NativeTokenHomeUpgradeableMetaData contains all meta data concerning the NativeTokenHomeUpgradeable contract. +var NativeTokenHomeUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"enumICMInitializable\",\"name\":\"init\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"CollateralAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialCollateralNeeded\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"RemoteRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"NATIVE_TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"addCollateral\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getRemoteTokenTransferrerSettings\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralNeeded\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"multiplyOnRemote\",\"type\":\"bool\"}],\"internalType\":\"structRemoteTokenTransferrerSettings\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getTransferredBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"wrappedTokenAddress\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561000f575f80fd5b50604051614add380380614add83398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b6149908061014d5f395ff3fe60806040526004361061011e575f3560e01c80638da5cb5b1161009d578063c8511ada11610062578063c8511ada146103c2578063c868efaa146104a2578063d2cc7a70146104c1578063efb5b95e146104f4578063f2fde38b14610514575f80fd5b80638da5cb5b14610305578063909a6ac0146103415780639731429714610361578063b0b78b2614610390578063be203094146103a3575f80fd5b80635eb99514116100e35780635eb995141461028c57806362e3901b146102ab5780636e6eef8d146102cb578063715018a6146102de5780638bf2fa94146102f2575f80fd5b806310fe9ae8146101ac578063154d625a146102015780632b0d8f181461022e5780634213cf781461024d5780634511243e1461026d575f80fd5b366101a8575f805160206148db833981519152546001600160a01b031633146101a65760405162461bcd60e51b815260206004820152602f60248201527f4e6174697665546f6b656e486f6d653a20696e76616c6964207265636569766560448201526e103830bcb0b136329039b2b73232b960891b60648201526084015b60405180910390fd5b005b5f80fd5b3480156101b7575f80fd5b507f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e601546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b34801561020c575f80fd5b5061022061021b3660046139b3565b610533565b6040519081526020016101f8565b348015610239575f80fd5b506101a66102483660046139e1565b61057b565b348015610258575f80fd5b505f805160206148bb83398151915254610220565b348015610278575f80fd5b506101a66102873660046139e1565b610674565b348015610297575f80fd5b506101a66102a63660046139fc565b610763565b3480156102b6575f80fd5b506102205f805160206148bb83398151915281565b6101a66102d9366004613a13565b610777565b3480156102e9575f80fd5b506101a66107a0565b6101a6610300366004613a4a565b6107b3565b348015610310575f80fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03166101e4565b34801561034c575f80fd5b506102205f8051602061493b83398151915281565b34801561036c575f80fd5b5061038061037b3660046139e1565b6107cb565b60405190151581526020016101f8565b6101a661039e3660046139b3565b6107eb565b3480156103ae575f80fd5b506101a66103bd366004613a61565b6107fa565b3480156103cd575f80fd5b5061046b6103dc3660046139b3565b60408051608080820183525f808352602080840182905283850182905260609384018290529581525f805160206148fb83398151915286528381206001600160a01b039590951681529385529282902082519384018352805460ff9081161515855260018201549585019590955260028101549284019290925260039091015490921615159181019190915290565b6040516101f89190815115158152602080830151908201526040808301519082015260609182015115159181019190915260800190565b3480156104ad575f80fd5b506101a66104bc366004613ab1565b61090c565b3480156104cc575f80fd5b507fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0254610220565b3480156104ff575f80fd5b506102205f805160206148db83398151915281565b34801561051f575f80fd5b506101a661052e3660046139e1565b610ac9565b5f8281527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03851684529091529020545b92915050565b5f8051602061493b833981519152610591610b03565b6001600160a01b0382166105b75760405162461bcd60e51b815260040161019d90613b32565b6105c18183610b0b565b156106245760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b606482015260840161019d565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b5f8051602061493b83398151915261068a610b03565b6001600160a01b0382166106b05760405162461bcd60e51b815260040161019d90613b32565b6106ba8183610b0b565b6107185760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b606482015260840161019d565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b61076b610b03565b61077481610b2c565b50565b61077461078f5f805160206148bb8339815191525490565b303361079a85613caa565b34610cc4565b6107a8610f27565b6107b15f610f82565b565b6107746107c536839003830183613d78565b34610ff2565b5f5f8051602061493b8339815191526107e48184610b0b565b9392505050565b6107f68282346111ac565b5050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561083e5750825b90505f826001600160401b031660011480156108595750303b155b905081158015610867575080155b156108855760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156108af57845460ff60401b1916600160401b1785555b6108bb8989898961139c565b831561090157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6109146113bb565b5f5f8051602061493b83398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561097f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a39190613e02565b1015610a0a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b606482015260840161019d565b610a148133610b0b565b15610a7a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b606482015260840161019d565b610aba858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061140592505050565b50610ac36117f9565b50505050565b610ad1610f27565b6001600160a01b038116610afa57604051631e4fbdf760e01b81525f600482015260240161019d565b61077481610f82565b6107b1610f27565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b5f8051602061493b83398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610b80573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ba49190613e02565b600283015490915081841115610c165760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b606482015260840161019d565b808411610c8b5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e00606482015260840161019d565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b5f8051602061491b8339815191528054600114610cf35760405162461bcd60e51b815260040161019d90613e19565b60028155610d0083611823565b60c08301516001600160a01b031615610d2b5760405162461bcd60e51b815260040161019d90613e5d565b5f80610d4b855f0151866020015186886101000151896101200151611a08565b915091505f604051806040016040528060026004811115610d6e57610d6e613ea3565b81526020016040518061010001604052808c81526020018b6001600160a01b031681526020018a6001600160a01b0316815260200189604001516001600160a01b03168152602001868152602001896060015181526020018960a0015181526020018960e001516001600160a01b0316815250604051602001610df19190613f04565b60405160208183030381529060405281525090505f610ed16040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b61010001516001600160a01b03168152602001878152508152602001896080015181526020015f6001600160401b03811115610e7a57610e7a613b80565b604051908082528060200260200182016040528015610ea3578160200160208202803683370190505b50815260200184604051602001610eba9190613fa2565b604051602081830303815290604052815250611bcd565b9050876001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168987604051610f0f929190613fe4565b60405180910390a35050600190925550505050505050565b33610f597f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146107b15760405163118cdaa760e01b815233600482015260240161019d565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f8051602061491b83398151915280546001146110215760405162461bcd60e51b815260040161019d90613e19565b6002815561102e83611ce8565b60e08301516001600160a01b0316156110595760405162461bcd60e51b815260040161019d90613e5d565b5f80611077855f015186602001518688606001518960800151611a08565b915091505f60405180604001604052806001600481111561109a5761109a613ea3565b8152602001604051806040016040528089604001516001600160a01b03168152602001868152506040516020016110d191906140c6565b60405160208183030381529060405281525090505f6111596040518060c00160405280895f0151815260200189602001516001600160a01b0316815260200160405180604001604052808b606001516001600160a01b031681526020018781525081526020018960c0015181526020015f6001600160401b03811115610e7a57610e7a613b80565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb5289876040516111979291906140e6565b60405180910390a35050600190925550505050565b5f8051602061491b83398151915280546001146111db5760405162461bcd60e51b815260040161019d90613e19565b60028082555f8581525f805160206148fb833981519152602090815260408083206001600160a01b03881684528252918290208251608081018452815460ff9081161515808352600184015494830194909452948201549381019390935260030154909216151560608201525f805160206148bb833981519152916112725760405162461bcd60e51b815260040161019d90614167565b5f8160200151116112cf5760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20636f6c6c61746572616c206e656564656044820152601960fa1b606482015260840161019d565b6112d884611d91565b93505f80826020015186106113075760208301515f92506112f990876141b0565b90508260200151955061131a565b85836020015161131791906141b0565b91505b5f88815260028501602090815260408083206001600160a01b038b168085529083529281902060010185905580518981529182018590528a917f6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6910160405180910390a3801561138e5761138e3382611db7565b505060019092555050505050565b6113a4611e75565b6113b2848484846012611ebe565b610ac381611ee3565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008054600119016113ff57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f5f805160206148bb83398151915290505f8280602001905181019061142b9190614205565b905060018151600481111561144257611442613ea3565b0361148a575f8160200151806020019051810190611460919061428d565b90505f61147287878460200151611f19565b9050611481825f015182611db7565b50505050505050565b60028151600481111561149f5761149f613ea3565b036115b8575f81602001518060200190518101906114bd91906142c5565b90505f6114cf87878460800151611f19565b825190915087146115355760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a206d69736d61746368656420736f7572636520626c6f60448201526918dad8da185a5b88125160b21b606482015260840161019d565b856001600160a01b031682602001516001600160a01b0316146115ae5760405162461bcd60e51b815260206004820152602b60248201527f546f6b656e486f6d653a206d69736d617463686564206f726967696e2073656e60448201526a646572206164647265737360a81b606482015260840161019d565b6114818282611fa4565b6003815160048111156115cd576115cd613ea3565b036116a1575f81602001518060200190518101906115eb919061438f565b90505f8061160388888560600151866080015161212a565b91509150611697604051806101000160405280855f0151815260200185602001516001600160a01b0316815260200185604001516001600160a01b03168152602001876001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018381526020015f81526020018560a0015181526020018560c001516001600160a01b0316815250836121d5565b5050505050505050565b6004815160048111156116b6576116b6613ea3565b036117b1575f81602001518060200190518101906116d49190614428565b90505f806116ed8888856080015186610140015161212a565b915091506116978888855f01516040518061016001604052808860200151815260200188604001516001600160a01b0316815260200188606001516001600160a01b031681526020018860a00151815260200188610100015181526020018860c0015181526020018861012001516001600160a01b031681526020018860e001516001600160a01b031681526020018a6001015f9054906101000a90046001600160a01b03166001600160a01b031681526020018681526020015f81525086612360565b5f815160048111156117c5576117c5613ea3565b036117f2575f81602001518060200190518101906117e39190614530565b90506117f086868361253d565b505b5050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b60408101516001600160a01b03166118905760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420636f6e7472616044820152696374206164647265737360b01b606482015260840161019d565b5f8160800151116118b35760405162461bcd60e51b815260040161019d90614592565b5f8160a00151116119125760405162461bcd60e51b815260206004820152602360248201527f546f6b656e486f6d653a207a65726f20726563697069656e7420676173206c696044820152621b5a5d60ea1b606482015260840161019d565b80608001518160a00151106119785760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420726563697069656e7420676173604482015265081b1a5b5a5d60d21b606482015260840161019d565b60e08101516001600160a01b03166119e55760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e486f6d653a207a65726f2066616c6c6261636b20726563697069656044820152696e74206164647265737360b01b606482015260840161019d565b610140810151156107745760405162461bcd60e51b815260040161019d906145d4565b5f8581525f805160206148fb833981519152602090815260408083206001600160a01b038816845282528083208151608081018352815460ff90811615158083526001840154958301959095526002830154938201939093526003909101549091161515606082015282915f805160206148bb8339815191529190611a9f5760405162461bcd60e51b815260040161019d90614167565b602081015115611b015760405162461bcd60e51b815260206004820152602760248201527f546f6b656e486f6d653a20636f6c6c61746572616c206e656564656420666f726044820152662072656d6f746560c81b606482015260840161019d565b611b0a87611d91565b96508415611b2057611b1d863387612944565b94505b5f611b34826040015183606001518a612a9d565b90505f8111611b855760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f207363616c656420616d6f756e74000000604482015260640161019d565b5f8a815260038401602090815260408083206001600160a01b038d16845290915281208054839290611bb8908490614615565b90915550909a95995094975050505050505050565b5f80611bd7612ab3565b60408401516020015190915015611c7c576040830151516001600160a01b0316611c595760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b606482015260840161019d565b604083015160208101519051611c7c916001600160a01b03909116908390612ba3565b604051630624488560e41b81526001600160a01b03821690636244885090611ca8908690600401614628565b6020604051808303815f875af1158015611cc4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107e49190613e02565b60408101516001600160a01b0316611d4c5760405162461bcd60e51b815260206004820152602160248201527f546f6b656e486f6d653a207a65726f20726563697069656e74206164647265736044820152607360f81b606482015260840161019d565b5f8160c0015111611d6f5760405162461bcd60e51b815260040161019d90614592565b60a0810151156107745760405162461bcd60e51b815260040161019d906145d4565b5f805160206148db83398151915280545f91906107e4906001600160a01b031684612c2a565b6040518181525f805160206148db833981519152906001600160a01b038416907f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b9060200160405180910390a28054604051632e1a7d4d60e01b8152600481018490526001600160a01b0390911690632e1a7d4d906024015f604051808303815f87803b158015611e46575f80fd5b505af1158015611e58573d5f803e3d5ffd5b50611e70925050506001600160a01b03841683612dcf565b505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166107b157604051631afcd79f60e31b815260040160405180910390fd5b611ec6611e75565b611ed1858585612e62565b611ed9612e7d565b6117f28282612e8d565b611eeb611e75565b5f805160206148db83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b5f8381525f805160206148fb833981519152602090815260408083206001600160a01b038616845282528083208151608081018352815460ff9081161515825260018301549482019490945260028201549281019290925260030154909116151560608201525f805160206148bb83398151915290611f9a81878787612ff4565b9695505050505050565b5f5f805160206148db8339815191528054604051632e1a7d4d60e01b8152600481018590529192506001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015611ff6575f80fd5b505af1158015612008573d5f803e3d5ffd5b50508451602086015160408088015160a089015191515f965061203195509091906024016146df565b60408051601f198184030181529190526020810180516001600160e01b031663161b12ff60e11b17905260c085015160608601519192505f9161207791908690856130e2565b905080156120cb5784606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4856040516120be91815260200190565b60405180910390a26117f2565b84606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb08560405161210a91815260200190565b60405180910390a260e08501516117f2906001600160a01b031685612dcf565b5f8481525f805160206148fb833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff90811615158252600183015494820194909452600282015492810192909252600301549091161515606082015281905f805160206148bb83398151915290826121ae828a8a8a612ff4565b90505f6121c483604001518460600151896131b2565b919a91995090975050505050505050565b5f8051602061491b83398151915280546001146122045760405162461bcd60e51b815260040161019d90613e19565b6002815561221183611ce8565b5f612229845f015185602001518587608001516131bf565b9050805f03612246576122408460e0015184611db7565b50612358565b604080518082019091525f908060018152602001604051806040016040528088604001516001600160a01b031681526020018581525060405160200161228c91906140c6565b60405160208183030381529060405281525090505f6123186040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a606001516001600160a01b031681526020018a6080015181525081526020018860c0015181526020015f6001600160401b03811115610e7a57610e7a613b80565b9050807f825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0878560405161234c9291906140e6565b60405180910390a25050505b600190555050565b5f8051602061491b833981519152805460011461238f5760405162461bcd60e51b815260040161019d90613e19565b6002815561239c83611823565b5f6123b5845f01518560200151858761012001516131bf565b9050805f036123d2576123cc8460c0015184611db7565b50612532565b604080518082019091525f9080600281526020016040518061010001604052808b81526020018a6001600160a01b03168152602001896001600160a01b0316815260200188604001516001600160a01b03168152602001858152602001886060015181526020018860a0015181526020018860e001516001600160a01b03168152506040516020016124649190613f04565b60405160208183030381529060405281525090505f6124f26040518060c00160405280885f0151815260200188602001516001600160a01b0316815260200160405180604001604052808a61010001516001600160a01b031681526020018a61012001518152508152602001886080015181526020015f6001600160401b03811115610e7a57610e7a613b80565b9050807f42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb308785604051612526929190613fe4565b60405180910390a25050505b600190555050505050565b5f805160206148bb833981519152836125a45760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a207a65726f2072656d6f746520626c6f636b636861696044820152631b88125160e21b606482015260840161019d565b8054840361260c5760405162461bcd60e51b815260206004820152602f60248201527f546f6b656e486f6d653a2063616e6e6f742072656769737465722072656d6f7460448201526e329037b71039b0b6b29031b430b4b760891b606482015260840161019d565b6001600160a01b03831661267b5760405162461bcd60e51b815260206004820152603060248201527f546f6b656e486f6d653a207a65726f2072656d6f746520746f6b656e2074726160448201526f6e73666572726572206164647265737360801b606482015260840161019d565b5f84815260028201602090815260408083206001600160a01b038716845290915290205460ff16156126fb5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f746520616c726561647920726567697374604482015263195c995960e21b606482015260840161019d565b6012826040015160ff1611156127655760405162461bcd60e51b815260206004820152602960248201527f546f6b656e486f6d653a2072656d6f746520746f6b656e20646563696d616c73604482015268040e8dede40d0d2ced60bb1b606482015260840161019d565b6001810154602083015160ff908116600160a01b90920416146127d95760405162461bcd60e51b815260206004820152602660248201527f546f6b656e486f6d653a20696e76616c696420686f6d6520746f6b656e20646560448201526563696d616c7360d01b606482015260840161019d565b5f806127fa8360010160149054906101000a900460ff168560400151613330565b915091505f61280d8383875f01516131b2565b905081801561282757508451612824908490614724565b15155b1561283a57612837600182614615565b90505b6040518060800160405280600115158152602001828152602001848152602001831515815250846002015f8981526020019081526020015f205f886001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548160ff02191690831515021790555060208201518160010155604082015181600201556060820151816003015f6101000a81548160ff021916908315150217905550905050856001600160a01b0316877ff229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b9083886040015160405161293392919091825260ff16602082015260400190565b60405180910390a350505050505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa15801561298a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129ae9190613e02565b90506129c56001600160a01b038616853086613378565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612a09573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a2d9190613e02565b9050818111612a935760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840161019d565b611f9a82826141b0565b5f612aab84848460016133df565b949350505050565b5f8051602061493b83398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612b0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b319190614737565b9050612b3d8282610b0b565b156105755760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b606482015260840161019d565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612bf0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c149190613e02565b9050610ac38484612c258585614615565b613406565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa158015612c70573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c949190613e02565b9050836001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004015f604051808303818588803b158015612ccf575f80fd5b505af1158015612ce1573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201525f93506001600160a01b03881692506370a082319150602401602060405180830381865afa158015612d2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d4e9190613e02565b9050818111612dbc5760405162461bcd60e51b815260206004820152603460248201527f53616665577261707065644e6174697665546f6b656e4465706f7369743a2062604482015273185b185b98d9481b9bdd081a5b98dc99585cd95960621b606482015260840161019d565b612dc682826141b0565b95945050505050565b80471015612df25760405163cd78605960e01b815230600482015260240161019d565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114612e3b576040519150601f19603f3d011682016040523d82523d5f602084013e612e40565b606091505b5050905080611e7057604051630a12f52160e11b815260040160405180910390fd5b612e6a611e75565b612e748382613495565b611e70826134b7565b612e85611e75565b6107b16134c8565b612e95611e75565b6001600160a01b038216612eeb5760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e486f6d653a207a65726f20746f6b656e2061646472657373000000604482015260640161019d565b60128160ff161115612f4a5760405162461bcd60e51b815260206004820152602260248201527f546f6b656e486f6d653a20746f6b656e20646563696d616c7320746f6f2068696044820152610ced60f31b606482015260840161019d565b5f5f805160206148bb83398151915290506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f9e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fc29190613e02565b8155600101805460ff909216600160a01b026001600160a81b03199092166001600160a01b0390931692909217179055565b83515f906130145760405162461bcd60e51b815260040161019d90614167565b6020850151156130725760405162461bcd60e51b8152602060048201526024808201527f546f6b656e486f6d653a2072656d6f7465206e6f7420636f6c6c61746572616c6044820152631a5e995960e21b606482015260840161019d565b61307d8484846134dc565b5f61309186604001518760600151856131b2565b90505f8111612dc65760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e486f6d653a207a65726f20746f6b656e20616d6f756e7400000000604482015260640161019d565b5f845a10156131335760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e74206761730000000000604482015260640161019d565b834710156131835760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c7565000000604482015260640161019d565b826001600160a01b03163b5f0361319b57505f612aab565b5f805f84516020860188888bf19695505050505050565b5f612aab8484845f6133df565b5f8481525f805160206148fb833981519152602090815260408083206001600160a01b038716845282528083208151608081018352815460ff9081161580158352600184015495830195909552600283015493820193909352600390910154909116151560608201525f805160206148bb833981519152918061324557505f8160200151115b15613254575f92505050612aab565b8385116132b85760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e486f6d653a20696e73756666696369656e7420616d6f756e74207460448201526b6f20636f766572206665657360a01b606482015260840161019d565b6132c284866141b0565b94505f6132d88260400151836060015188612a9d565b9050805f036132ec575f9350505050612aab565b5f88815260038401602090815260408083206001600160a01b038b1684529091528120805483929061331f908490614615565b909155509098975050505050505050565b5f8060ff8085169084161181816133535761334b8587614752565b60ff16613361565b61335d8686614752565b60ff165b61336c90600a61484b565b96919550909350505050565b6040516001600160a01b038481166024830152838116604483015260648201839052610ac39186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506135c9565b5f811515841515036133fc576133f58584614856565b9050612aab565b612dc6858461486d565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052613457848261362a565b610ac3576040516001600160a01b0384811660248301525f604483015261348b91869182169063095ea7b3906064016133ad565b610ac384826135c9565b61349d611e75565b6134a56136c7565b6134ad6136d7565b6107f682826136df565b6134bf611e75565b61077481613863565b5f5f8051602061491b83398151915261181c565b5f8381527f9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e603602090815260408083206001600160a01b03861684529091529020545f805160206148bb83398151915290828110156135935760405162461bcd60e51b815260206004820152602e60248201527f546f6b656e486f6d653a20696e73756666696369656e7420746f6b656e20747260448201526d616e736665722062616c616e636560901b606482015260840161019d565b61359d83826141b0565b5f9586526003909201602090815260408087206001600160a01b03909616875294905250919092205550565b5f6135dd6001600160a01b0384168361386b565b905080515f141580156136015750808060200190518101906135ff9190614880565b155b15611e7057604051635274afe760e01b81526001600160a01b038416600482015260240161019d565b5f805f846001600160a01b031684604051613645919061489f565b5f604051808303815f865af19150503d805f811461367e576040519150601f19603f3d011682016040523d82523d5f602084013e613683565b606091505b50915091508180156136ad5750805115806136ad5750808060200190518101906136ad9190614880565b8015612dc65750505050506001600160a01b03163b151590565b6136cf611e75565b6107b1613878565b6107b1611e75565b6136e7611e75565b6001600160a01b0382166137635760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840161019d565b5f5f8051602061493b83398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137b5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137d99190613e02565b116138415760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b606482015260840161019d565b81546001600160a01b0319166001600160a01b038216178255610ac383610b2c565b610ad1611e75565b60606107e483835f613880565b6117f9611e75565b6060814710156138a55760405163cd78605960e01b815230600482015260240161019d565b5f80856001600160a01b031684866040516138c0919061489f565b5f6040518083038185875af1925050503d805f81146138fa576040519150601f19603f3d011682016040523d82523d5f602084013e6138ff565b606091505b5091509150611f9a86838360608261391f5761391a82613966565b6107e4565b815115801561393657506001600160a01b0384163b155b1561395f57604051639996b31560e01b81526001600160a01b038516600482015260240161019d565b50806107e4565b8051156139765780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610774575f80fd5b80356139ae8161398f565b919050565b5f80604083850312156139c4575f80fd5b8235915060208301356139d68161398f565b809150509250929050565b5f602082840312156139f1575f80fd5b81356107e48161398f565b5f60208284031215613a0c575f80fd5b5035919050565b5f60208284031215613a23575f80fd5b81356001600160401b03811115613a38575f80fd5b820161016081850312156107e4575f80fd5b5f6101008284031215613a5b575f80fd5b50919050565b5f805f8060808587031215613a74575f80fd5b8435613a7f8161398f565b93506020850135613a8f8161398f565b9250604085013591506060850135613aa68161398f565b939692955090935050565b5f805f8060608587031215613ac4575f80fd5b843593506020850135613ad68161398f565b925060408501356001600160401b0380821115613af1575f80fd5b818701915087601f830112613b04575f80fd5b813581811115613b12575f80fd5b886020828501011115613b23575f80fd5b95989497505060200194505050565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b60405161016081016001600160401b0381118282101715613bb757613bb7613b80565b60405290565b60405161010081016001600160401b0381118282101715613bb757613bb7613b80565b604080519081016001600160401b0381118282101715613bb757613bb7613b80565b604051601f8201601f191681016001600160401b0381118282101715613c2a57613c2a613b80565b604052919050565b5f6001600160401b03821115613c4a57613c4a613b80565b50601f01601f191660200190565b5f82601f830112613c67575f80fd5b8135613c7a613c7582613c32565b613c02565b818152846020838601011115613c8e575f80fd5b816020850160208301375f918101602001919091529392505050565b5f6101608236031215613cbb575f80fd5b613cc3613b94565b82358152613cd3602084016139a3565b6020820152613ce4604084016139a3565b604082015260608301356001600160401b03811115613d01575f80fd5b613d0d36828601613c58565b6060830152506080830135608082015260a083013560a0820152613d3360c084016139a3565b60c0820152613d4460e084016139a3565b60e0820152610100613d578185016139a3565b90820152610120838101359082015261014092830135928101929092525090565b5f6101008284031215613d89575f80fd5b613d91613bbd565b823581526020830135613da38161398f565b60208201526040830135613db68161398f565b6040820152613dc7606084016139a3565b60608201526080830135608082015260a083013560a082015260c083013560c0820152613df660e084016139a3565b60e08201529392505050565b5f60208284031215613e12575f80fd5b5051919050565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b60208082526026908201527f546f6b656e486f6d653a206e6f6e2d7a65726f206d756c74692d686f702066616040820152656c6c6261636b60d01b606082015260800190565b634e487b7160e01b5f52602160045260245ffd5b5f5b83811015613ed1578181015183820152602001613eb9565b50505f910152565b5f8151808452613ef0816020860160208601613eb7565b601f01601f19169290920160200192915050565b60208152815160208201525f602083015160018060a01b03808216604085015280604086015116606085015250506060830151613f4c60808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c0850152613f73610120850183613ed9565b915060c085015160e085015260e0850151613f98828601826001600160a01b03169052565b5090949350505050565b602081525f825160058110613fc557634e487b7160e01b5f52602160045260245ffd5b806020840152506020830151604080840152612aab6060840182613ed9565b60408152825160408201525f602084015161400a60608401826001600160a01b03169052565b5060408401516001600160a01b03166080830152606084015161016060a0840181905261403b6101a0850183613ed9565b9150608086015160c085015260a086015160e085015260c086015161010061406d818701836001600160a01b03169052565b60e0880151915061012061408b818801846001600160a01b03169052565b908801519150610140906140a9878301846001600160a01b03169052565b880151928601929092525090940151610180830152506020015290565b81516001600160a01b031681526020808301519082015260408101610575565b5f6101208201905083518252602084015160018060a01b03808216602085015280604087015116604085015280606087015116606085015250506080840151608083015260a084015160a083015260c084015160c083015260e084015161415860e08401826001600160a01b03169052565b50826101008301529392505050565b6020808252818101527f546f6b656e486f6d653a2072656d6f7465206e6f742072656769737465726564604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b818103818111156105755761057561419c565b5f82601f8301126141d2575f80fd5b81516141e0613c7582613c32565b8181528460208386010111156141f4575f80fd5b612aab826020830160208701613eb7565b5f60208284031215614215575f80fd5b81516001600160401b038082111561422b575f80fd5b908301906040828603121561423e575f80fd5b614246613be0565b825160058110614254575f80fd5b8152602083015182811115614267575f80fd5b614273878286016141c3565b60208301525095945050505050565b80516139ae8161398f565b5f6040828403121561429d575f80fd5b6142a5613be0565b82516142b08161398f565b81526020928301519281019290925250919050565b5f602082840312156142d5575f80fd5b81516001600160401b03808211156142eb575f80fd5b9083019061010082860312156142ff575f80fd5b614307613bbd565b8251815261431760208401614282565b602082015261432860408401614282565b604082015261433960608401614282565b60608201526080830151608082015260a083015182811115614359575f80fd5b614365878286016141c3565b60a08301525060c083015160c082015261438160e08401614282565b60e082015295945050505050565b5f60e0828403121561439f575f80fd5b60405160e081018181106001600160401b03821117156143c1576143c1613b80565b6040528251815260208301516143d68161398f565b602082015260408301516143e98161398f565b80604083015250606083015160608201526080830151608082015260a083015160a082015260c083015161441c8161398f565b60c08201529392505050565b5f60208284031215614438575f80fd5b81516001600160401b038082111561444e575f80fd5b908301906101608286031215614462575f80fd5b61446a613b94565b61447383614282565b81526020830151602082015261448b60408401614282565b604082015261449c60608401614282565b60608201526080830151608082015260a0830151828111156144bc575f80fd5b6144c8878286016141c3565b60a08301525060c083015160c08201526144e460e08401614282565b60e082015261010083810151908201526101209150614504828401614282565b9181019190915261014091820151918101919091529392505050565b805160ff811681146139ae575f80fd5b5f60608284031215614540575f80fd5b604051606081018181106001600160401b038211171561456257614562613b80565b6040528251815261457560208401614520565b602082015261458660408401614520565b60408201529392505050565b60208082526022908201527f546f6b656e486f6d653a207a65726f20726571756972656420676173206c696d6040820152611a5d60f21b606082015260800190565b60208082526021908201527f546f6b656e486f6d653a206e6f6e2d7a65726f207365636f6e646172792066656040820152606560f81b606082015260800190565b808201808211156105755761057561419c565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b808410156146b557845183168252938501936001939093019290850190614693565b5060a0880151878203601f190160e089015294506146d38186613ed9565b98975050505050505050565b8481526001600160a01b038481166020830152831660408201526080606082018190525f90611f9a90830184613ed9565b634e487b7160e01b5f52601260045260245ffd5b5f8261473257614732614710565b500690565b5f60208284031215614747575f80fd5b81516107e48161398f565b60ff82811682821603908111156105755761057561419c565b600181815b808511156147a557815f190482111561478b5761478b61419c565b8085161561479857918102915b93841c9390800290614770565b509250929050565b5f826147bb57506001610575565b816147c757505f610575565b81600181146147dd57600281146147e757614803565b6001915050610575565b60ff8411156147f8576147f861419c565b50506001821b610575565b5060208310610133831016604e8410600b8410161715614826575081810a610575565b614830838361476b565b805f19048211156148435761484361419c565b029392505050565b5f6107e483836147ad565b80820281158282048414176105755761057561419c565b5f8261487b5761487b614710565b500490565b5f60208284031215614890575f80fd5b815180151581146107e4575f80fd5b5f82516148b0818460208701613eb7565b919091019291505056fe9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e6003b5030f10c94fcbdaa3022348ff0b82dbd4c0c71339e41ff59d0bdc92179d6009316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e602d2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a26469706673582212208aefe04601f29da9580937e2939cbe475f4ee96d71382814d91dd556b00667c064736f6c63430008190033", +} + +// NativeTokenHomeUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenHomeUpgradeableMetaData.ABI instead. +var NativeTokenHomeUpgradeableABI = NativeTokenHomeUpgradeableMetaData.ABI + +// NativeTokenHomeUpgradeableBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenHomeUpgradeableMetaData.Bin instead. +var NativeTokenHomeUpgradeableBin = NativeTokenHomeUpgradeableMetaData.Bin + +// DeployNativeTokenHomeUpgradeable deploys a new Ethereum contract, binding an instance of NativeTokenHomeUpgradeable to it. +func DeployNativeTokenHomeUpgradeable(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *NativeTokenHomeUpgradeable, error) { + parsed, err := NativeTokenHomeUpgradeableMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NativeTokenHomeUpgradeableBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenHomeUpgradeable{NativeTokenHomeUpgradeableCaller: NativeTokenHomeUpgradeableCaller{contract: contract}, NativeTokenHomeUpgradeableTransactor: NativeTokenHomeUpgradeableTransactor{contract: contract}, NativeTokenHomeUpgradeableFilterer: NativeTokenHomeUpgradeableFilterer{contract: contract}}, nil +} + +// NativeTokenHomeUpgradeable is an auto generated Go binding around an Ethereum contract. +type NativeTokenHomeUpgradeable struct { + NativeTokenHomeUpgradeableCaller // Read-only binding to the contract + NativeTokenHomeUpgradeableTransactor // Write-only binding to the contract + NativeTokenHomeUpgradeableFilterer // Log filterer for contract events +} + +// NativeTokenHomeUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenHomeUpgradeableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenHomeUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenHomeUpgradeableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenHomeUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenHomeUpgradeableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenHomeUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenHomeUpgradeableSession struct { + Contract *NativeTokenHomeUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenHomeUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenHomeUpgradeableCallerSession struct { + Contract *NativeTokenHomeUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenHomeUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenHomeUpgradeableTransactorSession struct { + Contract *NativeTokenHomeUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenHomeUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenHomeUpgradeableRaw struct { + Contract *NativeTokenHomeUpgradeable // Generic contract binding to access the raw methods on +} + +// NativeTokenHomeUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenHomeUpgradeableCallerRaw struct { + Contract *NativeTokenHomeUpgradeableCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenHomeUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenHomeUpgradeableTransactorRaw struct { + Contract *NativeTokenHomeUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenHomeUpgradeable creates a new instance of NativeTokenHomeUpgradeable, bound to a specific deployed contract. +func NewNativeTokenHomeUpgradeable(address common.Address, backend bind.ContractBackend) (*NativeTokenHomeUpgradeable, error) { + contract, err := bindNativeTokenHomeUpgradeable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeable{NativeTokenHomeUpgradeableCaller: NativeTokenHomeUpgradeableCaller{contract: contract}, NativeTokenHomeUpgradeableTransactor: NativeTokenHomeUpgradeableTransactor{contract: contract}, NativeTokenHomeUpgradeableFilterer: NativeTokenHomeUpgradeableFilterer{contract: contract}}, nil +} + +// NewNativeTokenHomeUpgradeableCaller creates a new read-only instance of NativeTokenHomeUpgradeable, bound to a specific deployed contract. +func NewNativeTokenHomeUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenHomeUpgradeableCaller, error) { + contract, err := bindNativeTokenHomeUpgradeable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableCaller{contract: contract}, nil +} + +// NewNativeTokenHomeUpgradeableTransactor creates a new write-only instance of NativeTokenHomeUpgradeable, bound to a specific deployed contract. +func NewNativeTokenHomeUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenHomeUpgradeableTransactor, error) { + contract, err := bindNativeTokenHomeUpgradeable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTransactor{contract: contract}, nil +} + +// NewNativeTokenHomeUpgradeableFilterer creates a new log filterer instance of NativeTokenHomeUpgradeable, bound to a specific deployed contract. +func NewNativeTokenHomeUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenHomeUpgradeableFilterer, error) { + contract, err := bindNativeTokenHomeUpgradeable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableFilterer{contract: contract}, nil +} + +// bindNativeTokenHomeUpgradeable binds a generic wrapper to an already deployed contract. +func bindNativeTokenHomeUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenHomeUpgradeableMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenHomeUpgradeable.Contract.NativeTokenHomeUpgradeableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.NativeTokenHomeUpgradeableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.NativeTokenHomeUpgradeableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenHomeUpgradeable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.contract.Transact(opts, method, params...) +} + +// NATIVETOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0xefb5b95e. +// +// Solidity: function NATIVE_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) NATIVETOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "NATIVE_TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// NATIVETOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0xefb5b95e. +// +// Solidity: function NATIVE_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) NATIVETOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.NATIVETOKENHOMESTORAGELOCATION(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// NATIVETOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0xefb5b95e. +// +// Solidity: function NATIVE_TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) NATIVETOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.NATIVETOKENHOMESTORAGELOCATION(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) TOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.TOKENHOMESTORAGELOCATION(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.TOKENHOMESTORAGELOCATION(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.GetBlockchainID(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenHomeUpgradeable.Contract.GetBlockchainID(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenHomeUpgradeable.Contract.GetMinTeleporterVersion(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenHomeUpgradeable.Contract.GetMinTeleporterVersion(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) GetRemoteTokenTransferrerSettings(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "getRemoteTokenTransferrerSettings", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(RemoteTokenTransferrerSettings), err + } + + out0 := *abi.ConvertType(out[0], new(RemoteTokenTransferrerSettings)).(*RemoteTokenTransferrerSettings) + + return out0, err + +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _NativeTokenHomeUpgradeable.Contract.GetRemoteTokenTransferrerSettings(&_NativeTokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _NativeTokenHomeUpgradeable.Contract.GetRemoteTokenTransferrerSettings(&_NativeTokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) GetTokenAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "getTokenAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) GetTokenAddress() (common.Address, error) { + return _NativeTokenHomeUpgradeable.Contract.GetTokenAddress(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) GetTokenAddress() (common.Address, error) { + return _NativeTokenHomeUpgradeable.Contract.GetTokenAddress(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) GetTransferredBalance(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "getTransferredBalance", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _NativeTokenHomeUpgradeable.Contract.GetTransferredBalance(&_NativeTokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _NativeTokenHomeUpgradeable.Contract.GetTransferredBalance(&_NativeTokenHomeUpgradeable.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenHomeUpgradeable.Contract.IsTeleporterAddressPaused(&_NativeTokenHomeUpgradeable.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenHomeUpgradeable.Contract.IsTeleporterAddressPaused(&_NativeTokenHomeUpgradeable.CallOpts, teleporterAddress) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenHomeUpgradeable.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) Owner() (common.Address, error) { + return _NativeTokenHomeUpgradeable.Contract.Owner(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableCallerSession) Owner() (common.Address, error) { + return _NativeTokenHomeUpgradeable.Contract.Owner(&_NativeTokenHomeUpgradeable.CallOpts) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xb0b78b26. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) AddCollateral(opts *bind.TransactOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "addCollateral", remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xb0b78b26. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.AddCollateral(&_NativeTokenHomeUpgradeable.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// AddCollateral is a paid mutator transaction binding the contract method 0xb0b78b26. +// +// Solidity: function addCollateral(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) AddCollateral(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.AddCollateral(&_NativeTokenHomeUpgradeable.TransactOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0xbe203094. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address wrappedTokenAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) Initialize(opts *bind.TransactOpts, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, wrappedTokenAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "initialize", teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0xbe203094. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address wrappedTokenAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, wrappedTokenAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.Initialize(&_NativeTokenHomeUpgradeable.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0xbe203094. +// +// Solidity: function initialize(address teleporterRegistryAddress, address teleporterManager, uint256 minTeleporterVersion, address wrappedTokenAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) Initialize(teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int, wrappedTokenAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.Initialize(&_NativeTokenHomeUpgradeable.TransactOpts, teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.PauseTeleporterAddress(&_NativeTokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.PauseTeleporterAddress(&_NativeTokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.ReceiveTeleporterMessage(&_NativeTokenHomeUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.ReceiveTeleporterMessage(&_NativeTokenHomeUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.RenounceOwnership(&_NativeTokenHomeUpgradeable.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.RenounceOwnership(&_NativeTokenHomeUpgradeable.TransactOpts) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) Send(opts *bind.TransactOpts, input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "send", input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.Send(&_NativeTokenHomeUpgradeable.TransactOpts, input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.Send(&_NativeTokenHomeUpgradeable.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "sendAndCall", input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.SendAndCall(&_NativeTokenHomeUpgradeable.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.SendAndCall(&_NativeTokenHomeUpgradeable.TransactOpts, input) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.TransferOwnership(&_NativeTokenHomeUpgradeable.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.TransferOwnership(&_NativeTokenHomeUpgradeable.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.UnpauseTeleporterAddress(&_NativeTokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.UnpauseTeleporterAddress(&_NativeTokenHomeUpgradeable.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.UpdateMinTeleporterVersion(&_NativeTokenHomeUpgradeable.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.UpdateMinTeleporterVersion(&_NativeTokenHomeUpgradeable.TransactOpts, version) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableSession) Receive() (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.Receive(&_NativeTokenHomeUpgradeable.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableTransactorSession) Receive() (*types.Transaction, error) { + return _NativeTokenHomeUpgradeable.Contract.Receive(&_NativeTokenHomeUpgradeable.TransactOpts) +} + +// NativeTokenHomeUpgradeableCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableCallFailedIterator struct { + Event *NativeTokenHomeUpgradeableCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableCallFailed represents a CallFailed event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenHomeUpgradeableCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableCallFailedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableCallFailed) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseCallFailed(log types.Log) (*NativeTokenHomeUpgradeableCallFailed, error) { + event := new(NativeTokenHomeUpgradeableCallFailed) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableCallSucceededIterator struct { + Event *NativeTokenHomeUpgradeableCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableCallSucceeded represents a CallSucceeded event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenHomeUpgradeableCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableCallSucceededIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableCallSucceeded) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseCallSucceeded(log types.Log) (*NativeTokenHomeUpgradeableCallSucceeded, error) { + event := new(NativeTokenHomeUpgradeableCallSucceeded) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableCollateralAddedIterator is returned from FilterCollateralAdded and is used to iterate over the raw logs and unpacked data for CollateralAdded events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableCollateralAddedIterator struct { + Event *NativeTokenHomeUpgradeableCollateralAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableCollateralAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableCollateralAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableCollateralAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableCollateralAdded represents a CollateralAdded event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableCollateralAdded struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + Amount *big.Int + Remaining *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollateralAdded is a free log retrieval operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterCollateralAdded(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*NativeTokenHomeUpgradeableCollateralAddedIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableCollateralAddedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "CollateralAdded", logs: logs, sub: sub}, nil +} + +// WatchCollateralAdded is a free log subscription operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchCollateralAdded(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableCollateralAdded, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableCollateralAdded) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "CollateralAdded", 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 +} + +// ParseCollateralAdded is a log parse operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseCollateralAdded(log types.Log) (*NativeTokenHomeUpgradeableCollateralAdded, error) { + event := new(NativeTokenHomeUpgradeableCollateralAdded) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "CollateralAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableInitializedIterator struct { + Event *NativeTokenHomeUpgradeableInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableInitialized represents a Initialized event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*NativeTokenHomeUpgradeableInitializedIterator, error) { + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableInitializedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableInitialized) (event.Subscription, error) { + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableInitialized) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseInitialized(log types.Log) (*NativeTokenHomeUpgradeableInitialized, error) { + event := new(NativeTokenHomeUpgradeableInitialized) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableMinTeleporterVersionUpdatedIterator struct { + Event *NativeTokenHomeUpgradeableMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*NativeTokenHomeUpgradeableMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableMinTeleporterVersionUpdatedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*NativeTokenHomeUpgradeableMinTeleporterVersionUpdated, error) { + event := new(NativeTokenHomeUpgradeableMinTeleporterVersionUpdated) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableOwnershipTransferredIterator struct { + Event *NativeTokenHomeUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*NativeTokenHomeUpgradeableOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableOwnershipTransferredIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableOwnershipTransferred) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*NativeTokenHomeUpgradeableOwnershipTransferred, error) { + event := new(NativeTokenHomeUpgradeableOwnershipTransferred) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableRemoteRegisteredIterator is returned from FilterRemoteRegistered and is used to iterate over the raw logs and unpacked data for RemoteRegistered events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableRemoteRegisteredIterator struct { + Event *NativeTokenHomeUpgradeableRemoteRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableRemoteRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableRemoteRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableRemoteRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableRemoteRegistered represents a RemoteRegistered event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableRemoteRegistered struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + InitialCollateralNeeded *big.Int + TokenDecimals uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemoteRegistered is a free log retrieval operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterRemoteRegistered(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*NativeTokenHomeUpgradeableRemoteRegisteredIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableRemoteRegisteredIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "RemoteRegistered", logs: logs, sub: sub}, nil +} + +// WatchRemoteRegistered is a free log subscription operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchRemoteRegistered(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableRemoteRegistered, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableRemoteRegistered) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "RemoteRegistered", 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 +} + +// ParseRemoteRegistered is a log parse operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseRemoteRegistered(log types.Log) (*NativeTokenHomeUpgradeableRemoteRegistered, error) { + event := new(NativeTokenHomeUpgradeableRemoteRegistered) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "RemoteRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTeleporterAddressPausedIterator struct { + Event *NativeTokenHomeUpgradeableTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenHomeUpgradeableTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTeleporterAddressPausedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableTeleporterAddressPaused) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseTeleporterAddressPaused(log types.Log) (*NativeTokenHomeUpgradeableTeleporterAddressPaused, error) { + event := new(NativeTokenHomeUpgradeableTeleporterAddressPaused) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTeleporterAddressUnpausedIterator struct { + Event *NativeTokenHomeUpgradeableTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenHomeUpgradeableTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTeleporterAddressUnpausedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableTeleporterAddressUnpaused) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*NativeTokenHomeUpgradeableTeleporterAddressUnpaused, error) { + event := new(NativeTokenHomeUpgradeableTeleporterAddressUnpaused) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableTokensAndCallRoutedIterator is returned from FilterTokensAndCallRouted and is used to iterate over the raw logs and unpacked data for TokensAndCallRouted events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensAndCallRoutedIterator struct { + Event *NativeTokenHomeUpgradeableTokensAndCallRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableTokensAndCallRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableTokensAndCallRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableTokensAndCallRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableTokensAndCallRouted represents a TokensAndCallRouted event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensAndCallRouted struct { + TeleporterMessageID [32]byte + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallRouted is a free log retrieval operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterTokensAndCallRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*NativeTokenHomeUpgradeableTokensAndCallRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTokensAndCallRoutedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "TokensAndCallRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallRouted is a free log subscription operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchTokensAndCallRouted(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableTokensAndCallRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableTokensAndCallRouted) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallRouted", 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 +} + +// ParseTokensAndCallRouted is a log parse operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseTokensAndCallRouted(log types.Log) (*NativeTokenHomeUpgradeableTokensAndCallRouted, error) { + event := new(NativeTokenHomeUpgradeableTokensAndCallRouted) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensAndCallSentIterator struct { + Event *NativeTokenHomeUpgradeableTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableTokensAndCallSent represents a TokensAndCallSent event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenHomeUpgradeableTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTokensAndCallSentIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableTokensAndCallSent) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseTokensAndCallSent(log types.Log) (*NativeTokenHomeUpgradeableTokensAndCallSent, error) { + event := new(NativeTokenHomeUpgradeableTokensAndCallSent) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableTokensRoutedIterator is returned from FilterTokensRouted and is used to iterate over the raw logs and unpacked data for TokensRouted events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensRoutedIterator struct { + Event *NativeTokenHomeUpgradeableTokensRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableTokensRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableTokensRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableTokensRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableTokensRouted represents a TokensRouted event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensRouted struct { + TeleporterMessageID [32]byte + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensRouted is a free log retrieval operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterTokensRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*NativeTokenHomeUpgradeableTokensRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTokensRoutedIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "TokensRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensRouted is a free log subscription operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchTokensRouted(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableTokensRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableTokensRouted) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensRouted", 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 +} + +// ParseTokensRouted is a log parse operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseTokensRouted(log types.Log) (*NativeTokenHomeUpgradeableTokensRouted, error) { + event := new(NativeTokenHomeUpgradeableTokensRouted) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensSentIterator struct { + Event *NativeTokenHomeUpgradeableTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableTokensSent represents a TokensSent event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenHomeUpgradeableTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTokensSentIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableTokensSent) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseTokensSent(log types.Log) (*NativeTokenHomeUpgradeableTokensSent, error) { + event := new(NativeTokenHomeUpgradeableTokensSent) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenHomeUpgradeableTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensWithdrawnIterator struct { + Event *NativeTokenHomeUpgradeableTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenHomeUpgradeableTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenHomeUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenHomeUpgradeableTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenHomeUpgradeableTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenHomeUpgradeableTokensWithdrawn represents a TokensWithdrawn event raised by the NativeTokenHomeUpgradeable contract. +type NativeTokenHomeUpgradeableTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*NativeTokenHomeUpgradeableTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &NativeTokenHomeUpgradeableTokensWithdrawnIterator{contract: _NativeTokenHomeUpgradeable.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *NativeTokenHomeUpgradeableTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenHomeUpgradeable.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenHomeUpgradeableTokensWithdrawn) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenHomeUpgradeable *NativeTokenHomeUpgradeableFilterer) ParseTokensWithdrawn(log types.Log) (*NativeTokenHomeUpgradeableTokensWithdrawn, error) { + event := new(NativeTokenHomeUpgradeableTokensWithdrawn) + if err := _NativeTokenHomeUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenHome/TokenHome/TokenHome.go b/abi-bindings/go/ictt/TokenHome/TokenHome/TokenHome.go new file mode 100644 index 000000000..82ca513b9 --- /dev/null +++ b/abi-bindings/go/ictt/TokenHome/TokenHome/TokenHome.go @@ -0,0 +1,2696 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package tokenhome + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// RemoteTokenTransferrerSettings is an auto generated low-level Go binding around an user-defined struct. +type RemoteTokenTransferrerSettings struct { + Registered bool + CollateralNeeded *big.Int + TokenMultiplier *big.Int + MultiplyOnRemote bool +} + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// TokenHomeMetaData contains all meta data concerning the TokenHome contract. +var TokenHomeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"CollateralAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialCollateralNeeded\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"RemoteRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensRouted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_HOME_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getRemoteTokenTransferrerSettings\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"collateralNeeded\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokenMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"multiplyOnRemote\",\"type\":\"bool\"}],\"internalType\":\"structRemoteTokenTransferrerSettings\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"remoteBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"remoteTokenTransferrerAddress\",\"type\":\"address\"}],\"name\":\"getTransferredBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// TokenHomeABI is the input ABI used to generate the binding from. +// Deprecated: Use TokenHomeMetaData.ABI instead. +var TokenHomeABI = TokenHomeMetaData.ABI + +// TokenHome is an auto generated Go binding around an Ethereum contract. +type TokenHome struct { + TokenHomeCaller // Read-only binding to the contract + TokenHomeTransactor // Write-only binding to the contract + TokenHomeFilterer // Log filterer for contract events +} + +// TokenHomeCaller is an auto generated read-only Go binding around an Ethereum contract. +type TokenHomeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenHomeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TokenHomeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenHomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TokenHomeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenHomeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TokenHomeSession struct { + Contract *TokenHome // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenHomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TokenHomeCallerSession struct { + Contract *TokenHomeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TokenHomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TokenHomeTransactorSession struct { + Contract *TokenHomeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenHomeRaw is an auto generated low-level Go binding around an Ethereum contract. +type TokenHomeRaw struct { + Contract *TokenHome // Generic contract binding to access the raw methods on +} + +// TokenHomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TokenHomeCallerRaw struct { + Contract *TokenHomeCaller // Generic read-only contract binding to access the raw methods on +} + +// TokenHomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TokenHomeTransactorRaw struct { + Contract *TokenHomeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTokenHome creates a new instance of TokenHome, bound to a specific deployed contract. +func NewTokenHome(address common.Address, backend bind.ContractBackend) (*TokenHome, error) { + contract, err := bindTokenHome(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TokenHome{TokenHomeCaller: TokenHomeCaller{contract: contract}, TokenHomeTransactor: TokenHomeTransactor{contract: contract}, TokenHomeFilterer: TokenHomeFilterer{contract: contract}}, nil +} + +// NewTokenHomeCaller creates a new read-only instance of TokenHome, bound to a specific deployed contract. +func NewTokenHomeCaller(address common.Address, caller bind.ContractCaller) (*TokenHomeCaller, error) { + contract, err := bindTokenHome(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TokenHomeCaller{contract: contract}, nil +} + +// NewTokenHomeTransactor creates a new write-only instance of TokenHome, bound to a specific deployed contract. +func NewTokenHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenHomeTransactor, error) { + contract, err := bindTokenHome(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TokenHomeTransactor{contract: contract}, nil +} + +// NewTokenHomeFilterer creates a new log filterer instance of TokenHome, bound to a specific deployed contract. +func NewTokenHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenHomeFilterer, error) { + contract, err := bindTokenHome(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TokenHomeFilterer{contract: contract}, nil +} + +// bindTokenHome binds a generic wrapper to an already deployed contract. +func bindTokenHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TokenHomeMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TokenHome *TokenHomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenHome.Contract.TokenHomeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TokenHome *TokenHomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenHome.Contract.TokenHomeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TokenHome *TokenHomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenHome.Contract.TokenHomeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TokenHome *TokenHomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenHome.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TokenHome *TokenHomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenHome.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TokenHome *TokenHomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenHome.Contract.contract.Transact(opts, method, params...) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TokenHome *TokenHomeCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TokenHome *TokenHomeSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _TokenHome.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_TokenHome.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TokenHome *TokenHomeCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _TokenHome.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_TokenHome.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_TokenHome *TokenHomeCaller) TOKENHOMESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "TOKEN_HOME_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_TokenHome *TokenHomeSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _TokenHome.Contract.TOKENHOMESTORAGELOCATION(&_TokenHome.CallOpts) +} + +// TOKENHOMESTORAGELOCATION is a free data retrieval call binding the contract method 0x62e3901b. +// +// Solidity: function TOKEN_HOME_STORAGE_LOCATION() view returns(bytes32) +func (_TokenHome *TokenHomeCallerSession) TOKENHOMESTORAGELOCATION() ([32]byte, error) { + return _TokenHome.Contract.TOKENHOMESTORAGELOCATION(&_TokenHome.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_TokenHome *TokenHomeCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_TokenHome *TokenHomeSession) GetBlockchainID() ([32]byte, error) { + return _TokenHome.Contract.GetBlockchainID(&_TokenHome.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_TokenHome *TokenHomeCallerSession) GetBlockchainID() ([32]byte, error) { + return _TokenHome.Contract.GetBlockchainID(&_TokenHome.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TokenHome *TokenHomeCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TokenHome *TokenHomeSession) GetMinTeleporterVersion() (*big.Int, error) { + return _TokenHome.Contract.GetMinTeleporterVersion(&_TokenHome.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TokenHome *TokenHomeCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _TokenHome.Contract.GetMinTeleporterVersion(&_TokenHome.CallOpts) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_TokenHome *TokenHomeCaller) GetRemoteTokenTransferrerSettings(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "getRemoteTokenTransferrerSettings", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(RemoteTokenTransferrerSettings), err + } + + out0 := *abi.ConvertType(out[0], new(RemoteTokenTransferrerSettings)).(*RemoteTokenTransferrerSettings) + + return out0, err + +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_TokenHome *TokenHomeSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _TokenHome.Contract.GetRemoteTokenTransferrerSettings(&_TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetRemoteTokenTransferrerSettings is a free data retrieval call binding the contract method 0xc8511ada. +// +// Solidity: function getRemoteTokenTransferrerSettings(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns((bool,uint256,uint256,bool)) +func (_TokenHome *TokenHomeCallerSession) GetRemoteTokenTransferrerSettings(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (RemoteTokenTransferrerSettings, error) { + return _TokenHome.Contract.GetRemoteTokenTransferrerSettings(&_TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_TokenHome *TokenHomeCaller) GetTokenAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "getTokenAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_TokenHome *TokenHomeSession) GetTokenAddress() (common.Address, error) { + return _TokenHome.Contract.GetTokenAddress(&_TokenHome.CallOpts) +} + +// GetTokenAddress is a free data retrieval call binding the contract method 0x10fe9ae8. +// +// Solidity: function getTokenAddress() view returns(address) +func (_TokenHome *TokenHomeCallerSession) GetTokenAddress() (common.Address, error) { + return _TokenHome.Contract.GetTokenAddress(&_TokenHome.CallOpts) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_TokenHome *TokenHomeCaller) GetTransferredBalance(opts *bind.CallOpts, remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "getTransferredBalance", remoteBlockchainID, remoteTokenTransferrerAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_TokenHome *TokenHomeSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _TokenHome.Contract.GetTransferredBalance(&_TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// GetTransferredBalance is a free data retrieval call binding the contract method 0x154d625a. +// +// Solidity: function getTransferredBalance(bytes32 remoteBlockchainID, address remoteTokenTransferrerAddress) view returns(uint256) +func (_TokenHome *TokenHomeCallerSession) GetTransferredBalance(remoteBlockchainID [32]byte, remoteTokenTransferrerAddress common.Address) (*big.Int, error) { + return _TokenHome.Contract.GetTransferredBalance(&_TokenHome.CallOpts, remoteBlockchainID, remoteTokenTransferrerAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TokenHome *TokenHomeCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TokenHome *TokenHomeSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _TokenHome.Contract.IsTeleporterAddressPaused(&_TokenHome.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TokenHome *TokenHomeCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _TokenHome.Contract.IsTeleporterAddressPaused(&_TokenHome.CallOpts, teleporterAddress) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenHome *TokenHomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenHome.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenHome *TokenHomeSession) Owner() (common.Address, error) { + return _TokenHome.Contract.Owner(&_TokenHome.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenHome *TokenHomeCallerSession) Owner() (common.Address, error) { + return _TokenHome.Contract.Owner(&_TokenHome.CallOpts) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenHome *TokenHomeTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenHome.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenHome *TokenHomeSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenHome.Contract.PauseTeleporterAddress(&_TokenHome.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenHome *TokenHomeTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenHome.Contract.PauseTeleporterAddress(&_TokenHome.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TokenHome *TokenHomeTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TokenHome.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TokenHome *TokenHomeSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TokenHome.Contract.ReceiveTeleporterMessage(&_TokenHome.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TokenHome *TokenHomeTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TokenHome.Contract.ReceiveTeleporterMessage(&_TokenHome.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TokenHome *TokenHomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenHome.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TokenHome *TokenHomeSession) RenounceOwnership() (*types.Transaction, error) { + return _TokenHome.Contract.RenounceOwnership(&_TokenHome.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TokenHome *TokenHomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _TokenHome.Contract.RenounceOwnership(&_TokenHome.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenHome *TokenHomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TokenHome.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenHome *TokenHomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TokenHome.Contract.TransferOwnership(&_TokenHome.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenHome *TokenHomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TokenHome.Contract.TransferOwnership(&_TokenHome.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenHome *TokenHomeTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenHome.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenHome *TokenHomeSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenHome.Contract.UnpauseTeleporterAddress(&_TokenHome.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenHome *TokenHomeTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenHome.Contract.UnpauseTeleporterAddress(&_TokenHome.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TokenHome *TokenHomeTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _TokenHome.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TokenHome *TokenHomeSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _TokenHome.Contract.UpdateMinTeleporterVersion(&_TokenHome.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TokenHome *TokenHomeTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _TokenHome.Contract.UpdateMinTeleporterVersion(&_TokenHome.TransactOpts, version) +} + +// TokenHomeCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the TokenHome contract. +type TokenHomeCallFailedIterator struct { + Event *TokenHomeCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeCallFailed represents a CallFailed event raised by the TokenHome contract. +type TokenHomeCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_TokenHome *TokenHomeFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*TokenHomeCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &TokenHomeCallFailedIterator{contract: _TokenHome.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_TokenHome *TokenHomeFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *TokenHomeCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeCallFailed) + if err := _TokenHome.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_TokenHome *TokenHomeFilterer) ParseCallFailed(log types.Log) (*TokenHomeCallFailed, error) { + event := new(TokenHomeCallFailed) + if err := _TokenHome.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the TokenHome contract. +type TokenHomeCallSucceededIterator struct { + Event *TokenHomeCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeCallSucceeded represents a CallSucceeded event raised by the TokenHome contract. +type TokenHomeCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_TokenHome *TokenHomeFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*TokenHomeCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &TokenHomeCallSucceededIterator{contract: _TokenHome.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_TokenHome *TokenHomeFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *TokenHomeCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeCallSucceeded) + if err := _TokenHome.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_TokenHome *TokenHomeFilterer) ParseCallSucceeded(log types.Log) (*TokenHomeCallSucceeded, error) { + event := new(TokenHomeCallSucceeded) + if err := _TokenHome.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeCollateralAddedIterator is returned from FilterCollateralAdded and is used to iterate over the raw logs and unpacked data for CollateralAdded events raised by the TokenHome contract. +type TokenHomeCollateralAddedIterator struct { + Event *TokenHomeCollateralAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeCollateralAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeCollateralAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeCollateralAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeCollateralAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeCollateralAdded represents a CollateralAdded event raised by the TokenHome contract. +type TokenHomeCollateralAdded struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + Amount *big.Int + Remaining *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollateralAdded is a free log retrieval operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_TokenHome *TokenHomeFilterer) FilterCollateralAdded(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*TokenHomeCollateralAddedIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &TokenHomeCollateralAddedIterator{contract: _TokenHome.contract, event: "CollateralAdded", logs: logs, sub: sub}, nil +} + +// WatchCollateralAdded is a free log subscription operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_TokenHome *TokenHomeFilterer) WatchCollateralAdded(opts *bind.WatchOpts, sink chan<- *TokenHomeCollateralAdded, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "CollateralAdded", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeCollateralAdded) + if err := _TokenHome.contract.UnpackLog(event, "CollateralAdded", 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 +} + +// ParseCollateralAdded is a log parse operation binding the contract event 0x6769a5f9bfc8b6e0db839ab981cbf9239274ae72d2d035081a9157d43bd33cb6. +// +// Solidity: event CollateralAdded(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 amount, uint256 remaining) +func (_TokenHome *TokenHomeFilterer) ParseCollateralAdded(log types.Log) (*TokenHomeCollateralAdded, error) { + event := new(TokenHomeCollateralAdded) + if err := _TokenHome.contract.UnpackLog(event, "CollateralAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TokenHome contract. +type TokenHomeInitializedIterator struct { + Event *TokenHomeInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeInitialized represents a Initialized event raised by the TokenHome contract. +type TokenHomeInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TokenHome *TokenHomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*TokenHomeInitializedIterator, error) { + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TokenHomeInitializedIterator{contract: _TokenHome.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TokenHome *TokenHomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TokenHomeInitialized) (event.Subscription, error) { + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeInitialized) + if err := _TokenHome.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TokenHome *TokenHomeFilterer) ParseInitialized(log types.Log) (*TokenHomeInitialized, error) { + event := new(TokenHomeInitialized) + if err := _TokenHome.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the TokenHome contract. +type TokenHomeMinTeleporterVersionUpdatedIterator struct { + Event *TokenHomeMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the TokenHome contract. +type TokenHomeMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TokenHome *TokenHomeFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*TokenHomeMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &TokenHomeMinTeleporterVersionUpdatedIterator{contract: _TokenHome.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TokenHome *TokenHomeFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *TokenHomeMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeMinTeleporterVersionUpdated) + if err := _TokenHome.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TokenHome *TokenHomeFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*TokenHomeMinTeleporterVersionUpdated, error) { + event := new(TokenHomeMinTeleporterVersionUpdated) + if err := _TokenHome.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TokenHome contract. +type TokenHomeOwnershipTransferredIterator struct { + Event *TokenHomeOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeOwnershipTransferred represents a OwnershipTransferred event raised by the TokenHome contract. +type TokenHomeOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenHome *TokenHomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TokenHomeOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TokenHomeOwnershipTransferredIterator{contract: _TokenHome.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenHome *TokenHomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenHomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeOwnershipTransferred) + if err := _TokenHome.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenHome *TokenHomeFilterer) ParseOwnershipTransferred(log types.Log) (*TokenHomeOwnershipTransferred, error) { + event := new(TokenHomeOwnershipTransferred) + if err := _TokenHome.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeRemoteRegisteredIterator is returned from FilterRemoteRegistered and is used to iterate over the raw logs and unpacked data for RemoteRegistered events raised by the TokenHome contract. +type TokenHomeRemoteRegisteredIterator struct { + Event *TokenHomeRemoteRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeRemoteRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeRemoteRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeRemoteRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeRemoteRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeRemoteRegistered represents a RemoteRegistered event raised by the TokenHome contract. +type TokenHomeRemoteRegistered struct { + RemoteBlockchainID [32]byte + RemoteTokenTransferrerAddress common.Address + InitialCollateralNeeded *big.Int + TokenDecimals uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemoteRegistered is a free log retrieval operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_TokenHome *TokenHomeFilterer) FilterRemoteRegistered(opts *bind.FilterOpts, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (*TokenHomeRemoteRegisteredIterator, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return &TokenHomeRemoteRegisteredIterator{contract: _TokenHome.contract, event: "RemoteRegistered", logs: logs, sub: sub}, nil +} + +// WatchRemoteRegistered is a free log subscription operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_TokenHome *TokenHomeFilterer) WatchRemoteRegistered(opts *bind.WatchOpts, sink chan<- *TokenHomeRemoteRegistered, remoteBlockchainID [][32]byte, remoteTokenTransferrerAddress []common.Address) (event.Subscription, error) { + + var remoteBlockchainIDRule []interface{} + for _, remoteBlockchainIDItem := range remoteBlockchainID { + remoteBlockchainIDRule = append(remoteBlockchainIDRule, remoteBlockchainIDItem) + } + var remoteTokenTransferrerAddressRule []interface{} + for _, remoteTokenTransferrerAddressItem := range remoteTokenTransferrerAddress { + remoteTokenTransferrerAddressRule = append(remoteTokenTransferrerAddressRule, remoteTokenTransferrerAddressItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "RemoteRegistered", remoteBlockchainIDRule, remoteTokenTransferrerAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeRemoteRegistered) + if err := _TokenHome.contract.UnpackLog(event, "RemoteRegistered", 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 +} + +// ParseRemoteRegistered is a log parse operation binding the contract event 0xf229b02a51a4c8d5ef03a096ae0dd727d7b48b710d21b50ebebb560eef739b90. +// +// Solidity: event RemoteRegistered(bytes32 indexed remoteBlockchainID, address indexed remoteTokenTransferrerAddress, uint256 initialCollateralNeeded, uint8 tokenDecimals) +func (_TokenHome *TokenHomeFilterer) ParseRemoteRegistered(log types.Log) (*TokenHomeRemoteRegistered, error) { + event := new(TokenHomeRemoteRegistered) + if err := _TokenHome.contract.UnpackLog(event, "RemoteRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the TokenHome contract. +type TokenHomeTeleporterAddressPausedIterator struct { + Event *TokenHomeTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the TokenHome contract. +type TokenHomeTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TokenHome *TokenHomeFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*TokenHomeTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &TokenHomeTeleporterAddressPausedIterator{contract: _TokenHome.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TokenHome *TokenHomeFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *TokenHomeTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeTeleporterAddressPaused) + if err := _TokenHome.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TokenHome *TokenHomeFilterer) ParseTeleporterAddressPaused(log types.Log) (*TokenHomeTeleporterAddressPaused, error) { + event := new(TokenHomeTeleporterAddressPaused) + if err := _TokenHome.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the TokenHome contract. +type TokenHomeTeleporterAddressUnpausedIterator struct { + Event *TokenHomeTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the TokenHome contract. +type TokenHomeTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TokenHome *TokenHomeFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*TokenHomeTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &TokenHomeTeleporterAddressUnpausedIterator{contract: _TokenHome.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TokenHome *TokenHomeFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *TokenHomeTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeTeleporterAddressUnpaused) + if err := _TokenHome.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TokenHome *TokenHomeFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*TokenHomeTeleporterAddressUnpaused, error) { + event := new(TokenHomeTeleporterAddressUnpaused) + if err := _TokenHome.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeTokensAndCallRoutedIterator is returned from FilterTokensAndCallRouted and is used to iterate over the raw logs and unpacked data for TokensAndCallRouted events raised by the TokenHome contract. +type TokenHomeTokensAndCallRoutedIterator struct { + Event *TokenHomeTokensAndCallRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeTokensAndCallRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensAndCallRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeTokensAndCallRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeTokensAndCallRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeTokensAndCallRouted represents a TokensAndCallRouted event raised by the TokenHome contract. +type TokenHomeTokensAndCallRouted struct { + TeleporterMessageID [32]byte + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallRouted is a free log retrieval operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) FilterTokensAndCallRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*TokenHomeTokensAndCallRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &TokenHomeTokensAndCallRoutedIterator{contract: _TokenHome.contract, event: "TokensAndCallRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallRouted is a free log subscription operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) WatchTokensAndCallRouted(opts *bind.WatchOpts, sink chan<- *TokenHomeTokensAndCallRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "TokensAndCallRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeTokensAndCallRouted) + if err := _TokenHome.contract.UnpackLog(event, "TokensAndCallRouted", 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 +} + +// ParseTokensAndCallRouted is a log parse operation binding the contract event 0x42eff9005856e3c586b096d67211a566dc926052119fd7cc08023c70937ecb30. +// +// Solidity: event TokensAndCallRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) ParseTokensAndCallRouted(log types.Log) (*TokenHomeTokensAndCallRouted, error) { + event := new(TokenHomeTokensAndCallRouted) + if err := _TokenHome.contract.UnpackLog(event, "TokensAndCallRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the TokenHome contract. +type TokenHomeTokensAndCallSentIterator struct { + Event *TokenHomeTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeTokensAndCallSent represents a TokensAndCallSent event raised by the TokenHome contract. +type TokenHomeTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*TokenHomeTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &TokenHomeTokensAndCallSentIterator{contract: _TokenHome.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *TokenHomeTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeTokensAndCallSent) + if err := _TokenHome.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) ParseTokensAndCallSent(log types.Log) (*TokenHomeTokensAndCallSent, error) { + event := new(TokenHomeTokensAndCallSent) + if err := _TokenHome.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeTokensRoutedIterator is returned from FilterTokensRouted and is used to iterate over the raw logs and unpacked data for TokensRouted events raised by the TokenHome contract. +type TokenHomeTokensRoutedIterator struct { + Event *TokenHomeTokensRouted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeTokensRoutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensRouted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeTokensRoutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeTokensRoutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeTokensRouted represents a TokensRouted event raised by the TokenHome contract. +type TokenHomeTokensRouted struct { + TeleporterMessageID [32]byte + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensRouted is a free log retrieval operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) FilterTokensRouted(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*TokenHomeTokensRoutedIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &TokenHomeTokensRoutedIterator{contract: _TokenHome.contract, event: "TokensRouted", logs: logs, sub: sub}, nil +} + +// WatchTokensRouted is a free log subscription operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) WatchTokensRouted(opts *bind.WatchOpts, sink chan<- *TokenHomeTokensRouted, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "TokensRouted", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeTokensRouted) + if err := _TokenHome.contract.UnpackLog(event, "TokensRouted", 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 +} + +// ParseTokensRouted is a log parse operation binding the contract event 0x825080857c76cef4a1629c0705a7f8b4ef0282ddcafde0b6715c4fb34b68aaf0. +// +// Solidity: event TokensRouted(bytes32 indexed teleporterMessageID, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) ParseTokensRouted(log types.Log) (*TokenHomeTokensRouted, error) { + event := new(TokenHomeTokensRouted) + if err := _TokenHome.contract.UnpackLog(event, "TokensRouted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the TokenHome contract. +type TokenHomeTokensSentIterator struct { + Event *TokenHomeTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeTokensSent represents a TokensSent event raised by the TokenHome contract. +type TokenHomeTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*TokenHomeTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &TokenHomeTokensSentIterator{contract: _TokenHome.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *TokenHomeTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeTokensSent) + if err := _TokenHome.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenHome *TokenHomeFilterer) ParseTokensSent(log types.Log) (*TokenHomeTokensSent, error) { + event := new(TokenHomeTokensSent) + if err := _TokenHome.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenHomeTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the TokenHome contract. +type TokenHomeTokensWithdrawnIterator struct { + Event *TokenHomeTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenHomeTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenHomeTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenHomeTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenHomeTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenHomeTokensWithdrawn represents a TokensWithdrawn event raised by the TokenHome contract. +type TokenHomeTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_TokenHome *TokenHomeFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*TokenHomeTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenHome.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &TokenHomeTokensWithdrawnIterator{contract: _TokenHome.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_TokenHome *TokenHomeFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *TokenHomeTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenHome.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenHomeTokensWithdrawn) + if err := _TokenHome.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_TokenHome *TokenHomeFilterer) ParseTokensWithdrawn(log types.Log) (*TokenHomeTokensWithdrawn, error) { + event := new(TokenHomeTokensWithdrawn) + if err := _TokenHome.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote/ERC20TokenRemote.go b/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote/ERC20TokenRemote.go new file mode 100644 index 000000000..b706a55b7 --- /dev/null +++ b/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote/ERC20TokenRemote.go @@ -0,0 +1,3044 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokenremote + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// TokenRemoteSettings is an auto generated low-level Go binding around an user-defined struct. +type TokenRemoteSettings struct { + TeleporterRegistryAddress common.Address + TeleporterManager common.Address + MinTeleporterVersion *big.Int + TokenHomeBlockchainID [32]byte + TokenHomeAddress common.Address + TokenHomeDecimals uint8 +} + +// ERC20TokenRemoteMetaData contains all meta data concerning the ERC20TokenRemote contract. +var ERC20TokenRemoteMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"tokenHomeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"tokenHomeAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenHomeDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structTokenRemoteSettings\",\"name\":\"settings\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"tokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ERC20_TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_GAS_PER_WORD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_SEND_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTER_REMOTE_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"payloadSize\",\"type\":\"uint256\"}],\"name\":\"calculateNumWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInitialReserveImbalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getIsCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMultiplyOnRemote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"tokenHomeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"tokenHomeAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenHomeDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structTokenRemoteSettings\",\"name\":\"settings\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"tokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"registerWithHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161570338038061570383398101604081905261002e91610bf5565b61003a84848484610046565b50505050610f55565b50565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f8115801561008f5750825b90505f826001600160401b031660011480156100aa5750303b155b9050811580156100b8575080155b156100d65760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561010457845460ff60401b1916680100000000000000001785555b61011089898989610161565b831561015657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6101696101b3565b6101738383610203565b61017e845f83610219565b7f9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf62622300805460ff191660ff83161790555b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff1661020157604051631afcd79f60e31b815260040160405180910390fd5b565b61020b6101b3565b6102158282610250565b5050565b6102216101b3565b8251602084015160408501516102389291906102b3565b6102406102ce565b61024b8383836102de565b505050565b6102586101b3565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace036102a48482610d5a565b50600481016101ad8382610d5a565b6102bb6101b3565b6102c5838261062d565b61024b8261064f565b6102d66101b3565b610201610660565b6102e66101b3565b5f7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0090507302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037e9190610e19565b815560608401516103e95760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d6520626c6f60448201526918dad8da185a5b88125160b21b60648201526084015b60405180910390fd5b80546060850151036104635760405162461bcd60e51b815260206004820152603b60248201527f546f6b656e52656d6f74653a2063616e6e6f74206465706c6f7920746f20736160448201527f6d6520626c6f636b636861696e20617320746f6b656e20686f6d65000000000060648201526084016103e0565b60808401516001600160a01b03166104c95760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d65206164646044820152637265737360e01b60648201526084016103e0565b60128460a0015160ff1611156105335760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20746f6b656e20686f6d6520646563696d616c73604482015268040e8dede40d0d2ced60bb1b60648201526084016103e0565b60128260ff1611156105935760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a20746f6b656e20646563696d616c7320746f6f206044820152630d0d2ced60e31b60648201526084016103e0565b60608401516001820155608084015160028201805460058401869055600684018054871560ff1990911617905560a08701516001600160a01b039093166001600160a81b031990911617600160a01b60ff808516919091029190911760ff60a81b1916600160a81b9186169190910217905561060f908361068a565b60048301805460ff1916911515919091179055600390910155505050565b6106356101b3565b61063d6106d2565b6106456106e2565b61021582826106ea565b6106576101b3565b6100438161086e565b5f7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c75005b6001905550565b5f8060ff8085169084161181816106ad576106a58587610e44565b60ff166106bb565b6106b78686610e44565b60ff165b6106c690600a610f43565b96919550909350505050565b6106da6101b3565b6102016108a8565b6102016101b3565b6106f26101b3565b6001600160a01b03821661076e5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084016103e0565b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107f79190610e19565b1161084c5760405162461bcd60e51b815260206004820152603260248201525f805160206156e3833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016103e0565b81546001600160a01b0319166001600160a01b0382161782556101ad836108d7565b6108766101b3565b6001600160a01b03811661089f57604051631e4fbdf760e01b81525f60048201526024016103e0565b61004381610a6f565b6108b06101b3565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00610683565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa15801561093e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109629190610e19565b6002830154909150818411156109c15760405162461bcd60e51b815260206004820152603160248201525f805160206156e383398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016103e0565b808411610a365760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016103e0565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b0381118282101715610b1557610b15610adf565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610b4357610b43610adf565b604052919050565b80516001600160a01b0381168114610b61575f80fd5b919050565b805160ff81168114610b61575f80fd5b5f82601f830112610b85575f80fd5b81516001600160401b03811115610b9e57610b9e610adf565b6020610bb2601f8301601f19168201610b1b565b8281528582848701011115610bc5575f80fd5b5f5b83811015610be2578581018301518282018401528201610bc7565b505f928101909101919091529392505050565b5f805f80848603610120811215610c0a575f80fd5b60c0811215610c17575f80fd5b50610c20610af3565b610c2986610b4b565b8152610c3760208701610b4b565b60208201526040860151604082015260608601516060820152610c5c60808701610b4b565b6080820152610c6d60a08701610b66565b60a082015260c08601519094506001600160401b0380821115610c8e575f80fd5b610c9a88838901610b76565b945060e0870151915080821115610caf575f80fd5b50610cbc87828801610b76565b925050610ccc6101008601610b66565b905092959194509250565b600181811c90821680610ceb57607f821691505b602082108103610d0957634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561024b57805f5260205f20601f840160051c81016020851015610d345750805b601f840160051c820191505b81811015610d53575f8155600101610d40565b5050505050565b81516001600160401b03811115610d7357610d73610adf565b610d8781610d818454610cd7565b84610d0f565b602080601f831160018114610dba575f8415610da35750858301515b5f19600386901b1c1916600185901b178555610e11565b5f85815260208120601f198616915b82811015610de857888601518255948401946001909101908401610dc9565b5085821015610e0557878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f60208284031215610e29575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b60ff8281168282160390811115610e5d57610e5d610e30565b92915050565b600181815b80851115610e9d57815f1904821115610e8357610e83610e30565b80851615610e9057918102915b93841c9390800290610e68565b509250929050565b5f82610eb357506001610e5d565b81610ebf57505f610e5d565b8160018114610ed55760028114610edf57610efb565b6001915050610e5d565b60ff841115610ef057610ef0610e30565b50506001821b610e5d565b5060208310610133831016604e8410600b8410161715610f1e575081810a610e5d565b610f288383610e63565b805f1904821115610f3b57610f3b610e30565b029392505050565b5f610f4e8383610ea5565b9392505050565b61478180610f625f395ff3fe608060405234801561000f575f80fd5b506004361061021e575f3560e01c806370a082311161012a578063b8a46d02116100b4578063dd62ed3e11610079578063dd62ed3e146104bd578063e0fd9cb8146104d0578063ef793e2a146104d8578063f2fde38b146104e0578063f3f981d8146104f3575f80fd5b8063b8a46d0214610474578063c3cd692714610487578063c868efaa1461048f578063c9fe4ddf146104a2578063d2cc7a70146104b5575f80fd5b80638da5cb5b116100fa5780638da5cb5b146103ee578063909a6ac01461043257806395d89b4114610446578063973142971461044e578063a9059cbb14610461575f80fd5b806370a08231146103a0578063715018a6146103d457806371717c18146103dc5780637ee3779a146103e6575f80fd5b8063313ce567116101ab5780635507f3d11161017b5780635507f3d1146103365780635d16225d146103405780635eb995141461035357806362431a6514610366578063656900381461038d575f80fd5b8063313ce567146102c057806335cac159146102f45780634213cf781461031b5780634511243e14610323575f80fd5b806315beb59f116101f157806315beb59f1461027d57806318160ddd1461028657806323b872dd1461028e578063254ac160146102a15780632b0d8f18146102ab575f80fd5b806302a30c7d1461022257806306fdde031461023f5780630733c8c814610254578063095ea7b31461026a575b5f80fd5b61022a610506565b60405190151581526020015b60405180910390f35b61024761051d565b60405161023691906136ec565b61025c6105dd565b604051908152602001610236565b61022a610278366004613722565b6105f1565b61025c6105dc81565b61025c61060a565b61022a61029c36600461374c565b610625565b61025c6201fbd081565b6102be6102b936600461378a565b61064a565b005b7f9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf626223005460405160ff9091168152602001610236565b61025c7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0081565b61025c61074c565b6102be61033136600461378a565b61075d565b61025c6205302081565b6102be61034e3660046137a5565b61084c565b6102be6103613660046137d4565b61085a565b61025c7f9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf6262230081565b6102be61039b3660046137eb565b61086e565b61025c6103ae36600461378a565b6001600160a01b03165f9081525f8051602061470c833981519152602052604090205490565b6102be610878565b61025c6205573081565b61022a61088b565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b039091168152602001610236565b61025c5f8051602061472c83398151915281565b6102476108a2565b61022a61045c36600461378a565b6108e0565b61022a61046f366004613722565b6108f9565b6102be610482366004613823565b610906565b61041a610acd565b6102be61049d366004613839565b610aea565b6102be6104b03660046139f3565b610ca7565b61025c610db9565b61025c6104cb366004613adc565b610dce565b61025c610e17565b61025c610e2b565b6102be6104ee36600461378a565b610e3f565b61025c6105013660046137d4565b610e79565b5f80610510610e8f565b6006015460ff1692915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0380546060915f8051602061470c8339815191529161055b90613b13565b80601f016020809104026020016040519081016040528092919081815260200182805461058790613b13565b80156105d25780601f106105a9576101008083540402835291602001916105d2565b820191905f5260205f20905b8154815290600101906020018083116105b557829003601f168201915b505050505091505090565b5f806105e7610e8f565b6003015492915050565b5f336105fe818585610eb3565b60019150505b92915050565b5f805f8051602061470c8339815191525b6002015492915050565b5f33610632858285610ec5565b61063d858585610f22565b60019150505b9392505050565b5f8051602061472c833981519152610660610f7f565b6001600160a01b03821661068f5760405162461bcd60e51b815260040161068690613b45565b60405180910390fd5b6106998183610f87565b156106fc5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b6064820152608401610686565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b5f80610756610e8f565b5492915050565b5f8051602061472c833981519152610773610f7f565b6001600160a01b0382166107995760405162461bcd60e51b815260040161068690613b45565b6107a38183610f87565b6108015760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b6064820152608401610686565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b6108568282610fa8565b5050565b610862610f7f565b61086b81611030565b50565b61085682826111c8565b610880611250565b6108895f6112ab565b565b5f80610895610e8f565b6004015460ff1692915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f8051602061470c8339815191529161055b90613b13565b5f5f8051602061472c8339815191526106438184610f87565b5f336105fe818585610f22565b5f61090f610e8f565b6006810154909150610100900460ff161561096c5760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e52656d6f74653a20616c72656164792072656769737465726564006044820152606401610686565b604080516060808201835260058401548252600284015460ff600160a01b820481166020808601918252600160a81b9093048216858701908152865180880188525f808252885188518188015293518516848a01529151909316828601528651808303909501855260809091019095528082019290925291929091610a01906109f79087018761378a565b866020013561131b565b6040805160c0810182526001870154815260028701546001600160a01b031660208083019190915282518084018452939450610ac5939192830191908190610a4b908b018b61378a565b6001600160a01b0316815260209081018690529082526201fbd0908201526040015f5b604051908082528060200260200182016040528015610a97578160200160208202803683370190505b50815260200184604051602001610aae9190613ba7565b604051602081830303815290604052815250611363565b505050505050565b5f80610ad7610e8f565b600201546001600160a01b031692915050565b610af261147e565b5f5f8051602061472c83398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610b5d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b819190613be9565b1015610be85760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b6064820152608401610686565b610bf28133610f87565b15610c585760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b6064820152608401610686565b610c98858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506114c892505050565b50610ca16116df565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610ceb5750825b90505f826001600160401b03166001148015610d065750303b155b905081158015610d14575080155b15610d325760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610d5c57845460ff60401b1916600160401b1785555b610d6889898989611709565b8315610dae57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b5f805f8051602061472c83398151915261061b565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b5f80610e21610e8f565b6001015492915050565b5f80610e35610e8f565b6005015492915050565b610e47611250565b6001600160a01b038116610e7057604051631e4fbdf760e01b81525f6004820152602401610686565b61086b816112ab565b5f6005610e8783601f613c14565b901c92915050565b7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0090565b610ec08383836001611759565b505050565b5f610ed08484610dce565b90505f198114610ca15781811015610f1457604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610686565b610ca184848484035f611759565b6001600160a01b038316610f4b57604051634b637e8f60e11b81525f6004820152602401610686565b6001600160a01b038216610f745760405163ec442f0560e01b81525f6004820152602401610686565b610ec083838361183c565b610889611250565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c75008054600114610fea5760405162461bcd60e51b815260040161068690613c27565b600281555f610ff7610e8f565b905061100284611975565b600181015484350361101d576110188484611a60565b611027565b6110278484611be4565b50600190555050565b5f8051602061472c83398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015611084573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a89190613be9565b60028301549091508184111561111a5760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b6064820152608401610686565b80841161118f5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e006064820152608401610686565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500805460011461120a5760405162461bcd60e51b815260040161068690613c27565b600281555f611217610e8f565b905061122284611daf565b600181015484350361123e576112388484611fe9565b50611248565b61123884846121f8565b600190555050565b336112827f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146108895760405163118cdaa760e01b8152336004820152602401610686565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f815f0361132a57505f610604565b306001600160a01b0384160361135857611346335b3084610ec5565b611351333084610f22565b5080610604565b610643833384612494565b5f8061136d6125f7565b60408401516020015190915015611412576040830151516001600160a01b03166113ef5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b6064820152608401610686565b604083015160208101519051611412916001600160a01b039091169083906126e7565b604051630624488560e41b81526001600160a01b0382169063624488509061143e908690600401613c6b565b6020604051808303815f875af115801561145a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106439190613be9565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008054600119016114c257604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f6114d1610e8f565b9050806001015484146115385760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20696e76616c696420736f7572636520626c6f636044820152681ad8da185a5b88125160ba1b6064820152608401610686565b60028101546001600160a01b038481169116146115aa5760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a20696e76616c6964206f726967696e2073656e646044820152696572206164647265737360b01b6064820152608401610686565b5f828060200190518101906115bf9190613d64565b6006830154909150610100900460ff1615806115e05750600682015460ff16155b156115f75760068201805461ffff19166101011790555b60018151600481111561160c5761160c613b93565b03611643575f816020015180602001905181019061162a9190613dec565b905061163d815f0151826020015161276e565b506116d8565b60028151600481111561165857611658613b93565b03611686575f81602001518060200190518101906116769190613e24565b905061163d8182608001516127bb565b60405162461bcd60e51b815260206004820152602160248201527f546f6b656e52656d6f74653a20696e76616c6964206d657373616765207479706044820152606560f81b6064820152608401610686565b5050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b611711612914565b61171b838361295d565b611726845f8361296f565b7f9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf62622300805460ff191660ff8316179055610ca1565b5f8051602061470c8339815191526001600160a01b0385166117905760405163e602df0560e01b81525f6004820152602401610686565b6001600160a01b0384166117b957604051634a1406b160e11b81525f6004820152602401610686565b6001600160a01b038086165f908152600183016020908152604080832093881683529290522083905581156116d857836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161182d91815260200190565b60405180910390a35050505050565b5f8051602061470c8339815191526001600160a01b0384166118765781816002015f82825461186b9190613c14565b909155506118e69050565b6001600160a01b0384165f90815260208290526040902054828110156118c85760405163391434e360e21b81526001600160a01b03861660048201526024810182905260448101849052606401610686565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b038316611904576002810180548390039055611922565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161196791815260200190565b60405180910390a350505050565b5f611986606083016040840161378a565b6001600160a01b0316036119e85760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e74206164647260448201526265737360e81b6064820152608401610686565b5f8160c0013511611a0b5760405162461bcd60e51b815260040161068690613eee565b8035611a295760405162461bcd60e51b815260040161068690613f32565b5f611a3a604083016020840161378a565b6001600160a01b03160361086b5760405162461bcd60e51b815260040161068690613f7d565b5f611a69610e8f565b9050611a99611a7e604085016020860161378a565b60a0850135611a94610100870160e0880161378a565b6129a0565b5f611abd83611aae608087016060880161378a565b86608001358760a00135612a9d565b6040805180820190915291945091505f9080600181526020016040518060400160405280886040016020810190611af4919061378a565b6001600160a01b0316815260200187815250604051602001611b169190613fda565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92611b969282019080611b6e60808c0160608d0161378a565b6001600160a01b03168152602090810188905290825260c08a0135908201526040015f610a6e565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb528888604051611bd4929190613ffa565b60405180910390a3505050505050565b5f611bed610e8f565b9050611c1a8335611c04604086016020870161378a565b611c15610100870160e0880161378a565b612b60565b5f611c2f83611aae608087016060880161378a565b60408051808201825260038152815160e081018352883581529396509193505f9260208084019282820191611c68918b01908b0161378a565b6001600160a01b03168152602001611c8660608a0160408b0161378a565b6001600160a01b031681526020810188905260a0890135604082015260c08901356060820152608001611cc06101008a0160e08b0161378a565b6001600160a01b03169052604051611d309190602001815181526020808301516001600160a01b0390811691830191909152604080840151821690830152606080840151908301526080808401519083015260a0808401519083015260c092830151169181019190915260e00190565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92611b969282019080611d8860808c0160608d0161378a565b6001600160a01b03168152602090810188905290825262053020908201526040015f610a6e565b8035611dcd5760405162461bcd60e51b815260040161068690613f32565b5f611dde604083016020840161378a565b6001600160a01b031603611e045760405162461bcd60e51b815260040161068690613f7d565b5f611e15606083016040840161378a565b6001600160a01b031603611e805760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420636f6e7460448201526b72616374206164647265737360a01b6064820152608401610686565b5f816080013511611ea35760405162461bcd60e51b815260040161068690613eee565b5f8160a0013511611f045760405162461bcd60e51b815260206004820152602560248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420676173206044820152641b1a5b5a5d60da1b6064820152608401610686565b80608001358160a0013510611f6c5760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a20696e76616c696420726563697069656e742067604482015267185cc81b1a5b5a5d60c21b6064820152608401610686565b5f611f7e610100830160e0840161378a565b6001600160a01b03160361086b5760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f2066616c6c6261636b20726563697060448201526b69656e74206164647265737360a01b6064820152608401610686565b5f611ff2610e8f565b905061201d612007604085016020860161378a565b610140850135611a9460e0870160c0880161378a565b5f612045836120346101208701610100880161378a565b866101200135876101400135612a9d565b6040805180820190915291945091505f908060028152602001604051806101000160405280865f01548152602001306001600160a01b031681526020016120893390565b6001600160a01b031681526020016120a760608a0160408b0161378a565b6001600160a01b03168152602081018890526040016120c960608a018a614099565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a0890135602082015260400161211d6101008a0160e08b0161378a565b6001600160a01b0316905260405161213891906020016140db565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f926121ba92820190806121926101208c016101008d0161378a565b6001600160a01b03168152602090810188905290825260808a0135908201526040015f610a6e565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168888604051611bd49291906141e2565b5f612201610e8f565b90506122288335612218604086016020870161378a565b611c1560e0870160c0880161378a565b5f61223f836120346101208701610100880161378a565b6040805180820190915291945091505f90806004815260200160405180610160016040528061226b3390565b6001600160a01b03168152602001885f01358152602001886020016020810190612295919061378a565b6001600160a01b031681526020016122b360608a0160408b0161378a565b6001600160a01b03168152602081018890526040016122d560608a018a614099565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a089013560208201526040016123296101008a0160e08b0161378a565b6001600160a01b031681526080890135602082015260400161235160e08a0160c08b0161378a565b6001600160a01b031681526101408901356020918201526040516123769291016142f0565b60408051601f19818403018152919052905290505f6105dc6123a561239e6060890189614099565b9050610e79565b6123af91906143cd565b6123bc9062055730613c14565b6040805160c0810182526001870154815260028701546001600160a01b03166020820152815180830183529293505f9261244592820190806124066101208d016101008e0161378a565b6001600160a01b031681526020908101899052908252818101869052604080515f815280830182528184015251606090920191610aae91889101613ba7565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b1689896040516124839291906141e2565b60405180910390a350505050505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa1580156124da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124fe9190613be9565b90506125156001600160a01b038616853086612bfe565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061257d9190613be9565b90508181116125e35760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610686565b6125ed82826143e4565b9695505050505050565b5f8051602061472c83398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612651573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267591906143f7565b90506126818282610f87565b156106045760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b6064820152608401610686565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612734573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127589190613be9565b9050610ca184846127698585613c14565b612c65565b816001600160a01b03167f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b826040516127a991815260200190565b60405180910390a26108568282612cf4565b6127c53082612cf4565b6127d430836060015183610eb3565b5f825f01518360200151846040015130858760a001516040516024016127ff96959493929190614412565b60408051601f198184030181529190526020810180516001600160e01b03166394395edd60e01b17905260c084015160608501519192505f91612843919084612d28565b90505f612854308660600151610dce565b90506128653086606001515f610eb3565b81156128b75784606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4856040516128aa91815260200190565b60405180910390a26128ff565b84606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0856040516128f691815260200190565b60405180910390a25b80156116d8576116d8308660e0015183610f22565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661088957604051631afcd79f60e31b815260040160405180910390fd5b612965612914565b6108568282612d3d565b612977612914565b61298d835f015184602001518560400151612d8d565b612995612da8565b610ec0838383612db8565b5f6129a9610e8f565b60028101549091506001600160a01b038581169116146129db5760405162461bcd60e51b815260040161068690614452565b8215612a355760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f207365636f6e646172792060448201526266656560e81b6064820152608401610686565b6001600160a01b03821615610ca15760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f206d756c74692d686f702060448201526766616c6c6261636b60c01b6064820152608401610686565b5f805f612aa8610e8f565b9050612ab3876130dc565b9650612abf868661131b565b60038201546004830154919650612ad99160ff16866130f4565b60038201546004830154612af1919060ff168a6130f4565b11612b535760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a20696e73756666696369656e7420746f6b656e7360448201526b103a37903a3930b739b332b960a11b6064820152608401610686565b5094959294509192505050565b5f612b69610e8f565b80549091508403612b9c57306001600160a01b03841603612b9c5760405162461bcd60e51b815260040161068690614452565b6001600160a01b038216610ca15760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f206d756c74692d686f702066616c6c6044820152636261636b60e01b6064820152608401610686565b6040516001600160a01b038481166024830152838116604483015260648201839052610ca19186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613101565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612cb68482613162565b610ca1576040516001600160a01b0384811660248301525f6044830152612cea91869182169063095ea7b390606401612c33565b610ca18482613101565b6001600160a01b038216612d1d5760405163ec442f0560e01b81525f6004820152602401610686565b6108565f838361183c565b5f612d35845f8585613203565b949350505050565b612d45612914565b5f8051602061470c8339815191527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03612d7e84826144f3565b5060048101610ca183826144f3565b612d95612914565b612d9f83826132d3565b610ec0826132f5565b612db0612914565b610889613306565b612dc0612914565b5f612dc9610e8f565b90506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e0e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e329190613be9565b81556060840151612e985760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d6520626c6f60448201526918dad8da185a5b88125160b21b6064820152608401610686565b8054606085015103612f125760405162461bcd60e51b815260206004820152603b60248201527f546f6b656e52656d6f74653a2063616e6e6f74206465706c6f7920746f20736160448201527f6d6520626c6f636b636861696e20617320746f6b656e20686f6d6500000000006064820152608401610686565b60808401516001600160a01b0316612f785760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d65206164646044820152637265737360e01b6064820152608401610686565b60128460a0015160ff161115612fe25760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20746f6b656e20686f6d6520646563696d616c73604482015268040e8dede40d0d2ced60bb1b6064820152608401610686565b60128260ff1611156130425760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a20746f6b656e20646563696d616c7320746f6f206044820152630d0d2ced60e31b6064820152608401610686565b60608401516001820155608084015160028201805460058401869055600684018054871560ff1990911617905560a08701516001600160a01b039093166001600160a81b031990911617600160a01b60ff808516919091029190911760ff60a81b1916600160a81b918616919091021790556130be908361332d565b60048301805460ff1916911515919091179055600390910155505050565b5f6130e63361133f565b6130f03383613377565b5090565b5f612d358484845f6133ab565b5f6131156001600160a01b038416836133d2565b905080515f1415801561313957508080602001905181019061313791906145ae565b155b15610ec057604051635274afe760e01b81526001600160a01b0384166004820152602401610686565b5f805f846001600160a01b03168460405161317d91906145cd565b5f604051808303815f865af19150503d805f81146131b6576040519150601f19603f3d011682016040523d82523d5f602084013e6131bb565b606091505b50915091508180156131e55750805115806131e55750808060200190518101906131e591906145ae565b80156131fa57505f856001600160a01b03163b115b95945050505050565b5f845a10156132545760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e742067617300000000006044820152606401610686565b834710156132a45760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c75650000006044820152606401610686565b826001600160a01b03163b5f036132bc57505f612d35565b5f805f84516020860188888bf19695505050505050565b6132db612914565b6132e36133df565b6132eb6133ef565b61085682826133f7565b6132fd612914565b61086b8161357b565b5f7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500611702565b5f8060ff8085169084161181816133505761334885876145e8565b60ff1661335e565b61335a86866145e8565b60ff165b61336990600a6146e1565b9350909150505b9250929050565b6001600160a01b0382166133a057604051634b637e8f60e11b81525f6004820152602401610686565b610856825f8361183c565b5f811515841515036133c8576133c185846143cd565b9050612d35565b6131fa85846146ec565b606061064383835f613583565b6133e7612914565b610889613612565b610889612914565b6133ff612914565b6001600160a01b03821661347b5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f7274657220726567697374727920616464726573730000000000000000006064820152608401610686565b5f5f8051602061472c83398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134f19190613be9565b116135595760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b6064820152608401610686565b81546001600160a01b0319166001600160a01b038216178255610ca183611030565b610e47612914565b6060814710156135a85760405163cd78605960e01b8152306004820152602401610686565b5f80856001600160a01b031684866040516135c391906145cd565b5f6040518083038185875af1925050503d805f81146135fd576040519150601f19603f3d011682016040523d82523d5f602084013e613602565b606091505b50915091506125ed86838361361a565b6116df612914565b60608261362f5761362a82613676565b610643565b815115801561364657506001600160a01b0384163b155b1561366f57604051639996b31560e01b81526001600160a01b0385166004820152602401610686565b5080610643565b8051156136865780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f5b838110156136b95781810151838201526020016136a1565b50505f910152565b5f81518084526136d881602086016020860161369f565b601f01601f19169290920160200192915050565b602081525f61064360208301846136c1565b6001600160a01b038116811461086b575f80fd5b803561371d816136fe565b919050565b5f8060408385031215613733575f80fd5b823561373e816136fe565b946020939093013593505050565b5f805f6060848603121561375e575f80fd5b8335613769816136fe565b92506020840135613779816136fe565b929592945050506040919091013590565b5f6020828403121561379a575f80fd5b8135610643816136fe565b5f808284036101208112156137b8575f80fd5b610100808212156137c7575f80fd5b9395938601359450505050565b5f602082840312156137e4575f80fd5b5035919050565b5f80604083850312156137fc575f80fd5b82356001600160401b03811115613811575f80fd5b8301610160818603121561373e575f80fd5b5f60408284031215613833575f80fd5b50919050565b5f805f806060858703121561384c575f80fd5b84359350602085013561385e816136fe565b925060408501356001600160401b0380821115613879575f80fd5b818701915087601f83011261388c575f80fd5b81358181111561389a575f80fd5b8860208285010111156138ab575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b03811182821017156138f0576138f06138ba565b60405290565b604080519081016001600160401b03811182821017156138f0576138f06138ba565b60405161010081016001600160401b03811182821017156138f0576138f06138ba565b604051601f8201601f191681016001600160401b0381118282101715613963576139636138ba565b604052919050565b803560ff8116811461371d575f80fd5b5f6001600160401b03821115613993576139936138ba565b50601f01601f191660200190565b5f82601f8301126139b0575f80fd5b81356139c36139be8261397b565b61393b565b8181528460208386010111156139d7575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80848603610120811215613a08575f80fd5b60c0811215613a15575f80fd5b50613a1e6138ce565b8535613a29816136fe565b81526020860135613a39816136fe565b8060208301525060408601356040820152606086013560608201526080860135613a62816136fe565b6080820152613a7360a0870161396b565b60a0820152935060c08501356001600160401b0380821115613a93575f80fd5b613a9f888389016139a1565b945060e0870135915080821115613ab4575f80fd5b50613ac1878288016139a1565b925050613ad1610100860161396b565b905092959194509250565b5f8060408385031215613aed575f80fd5b8235613af8816136fe565b91506020830135613b08816136fe565b809150509250929050565b600181811c90821680613b2757607f821691505b60208210810361383357634e487b7160e01b5f52602260045260245ffd5b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b634e487b7160e01b5f52602160045260245ffd5b602081525f825160058110613bca57634e487b7160e01b5f52602160045260245ffd5b806020840152506020830151604080840152612d3560608401826136c1565b5f60208284031215613bf9575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561060457610604613c00565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b80841015613cf857845183168252938501936001939093019290850190613cd6565b5060a0880151878203601f190160e08901529450613d1681866136c1565b98975050505050505050565b5f82601f830112613d31575f80fd5b8151613d3f6139be8261397b565b818152846020838601011115613d53575f80fd5b612d3582602083016020870161369f565b5f60208284031215613d74575f80fd5b81516001600160401b0380821115613d8a575f80fd5b9083019060408286031215613d9d575f80fd5b613da56138f6565b825160058110613db3575f80fd5b8152602083015182811115613dc6575f80fd5b613dd287828601613d22565b60208301525095945050505050565b805161371d816136fe565b5f60408284031215613dfc575f80fd5b613e046138f6565b8251613e0f816136fe565b81526020928301519281019290925250919050565b5f60208284031215613e34575f80fd5b81516001600160401b0380821115613e4a575f80fd5b908301906101008286031215613e5e575f80fd5b613e66613918565b82518152613e7660208401613de1565b6020820152613e8760408401613de1565b6040820152613e9860608401613de1565b60608201526080830151608082015260a083015182811115613eb8575f80fd5b613ec487828601613d22565b60a08301525060c083015160c0820152613ee060e08401613de1565b60e082015295945050505050565b60208082526024908201527f546f6b656e52656d6f74653a207a65726f20726571756972656420676173206c6040820152631a5b5a5d60e21b606082015260800190565b6020808252602b908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20626c60408201526a1bd8dad8da185a5b88125160aa1b606082015260800190565b60208082526037908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20746f60408201527f6b656e207472616e736665727265722061646472657373000000000000000000606082015260800190565b81516001600160a01b031681526020808301519082015260408101610604565b8235815261012081016020840135614011816136fe565b6001600160a01b039081166020840152604085013590614030826136fe565b16604083015261404260608501613712565b6001600160a01b0381166060840152506080840135608083015260a084013560a083015260c084013560c083015261407c60e08501613712565b6001600160a01b031660e083015261010090910191909152919050565b5f808335601e198436030181126140ae575f80fd5b8301803591506001600160401b038211156140c7575f80fd5b602001915036819003821315613370575f80fd5b60208152815160208201525f602083015160018060a01b0380821660408501528060408601511660608501525050606083015161412360808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c085015261414a6101208501836136c1565b915060c085015160e085015260e085015161416f828601826001600160a01b03169052565b5090949350505050565b5f808335601e1984360301811261418e575f80fd5b83016020810192503590506001600160401b038111156141ac575f80fd5b803603821315613370575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60408152823560408201525f6141fa60208501613712565b6001600160a01b0316606083015261421460408501613712565b6001600160a01b0316608083015261422f6060850185614179565b6101608060a08601526142476101a0860183856141ba565b9250608087013560c086015260a087013560e086015261426960c08801613712565b9150610100614282818701846001600160a01b03169052565b61428e60e08901613712565b92506101206142a7818801856001600160a01b03169052565b6142b2828a01613712565b935061014091506142cd828801856001600160a01b03169052565b880135918601919091529095013561018084015260209092019290925292915050565b6020815261430a6020820183516001600160a01b03169052565b602082015160408201525f604083015161432f60608401826001600160a01b03169052565b5060608301516001600160a01b038116608084015250608083015160a083015260a08301516101608060c085015261436b6101808501836136c1565b915060c085015160e085015260e0850151610100614393818701836001600160a01b03169052565b8601516101208681019190915286015190506101406143bc818701836001600160a01b03169052565b959095015193019290925250919050565b808202811582820484141761060457610604613c00565b8181038181111561060457610604613c00565b5f60208284031215614407575f80fd5b8151610643816136fe565b8681526001600160a01b0386811660208301528581166040830152841660608201526080810183905260c060a082018190525f90613d16908301846136c1565b6020808252603a908201527f546f6b656e52656d6f74653a20696e76616c69642064657374696e6174696f6e60408201527f20746f6b656e207472616e736665727265722061646472657373000000000000606082015260800190565b601f821115610ec057805f5260205f20601f840160051c810160208510156144d45750805b601f840160051c820191505b818110156116d8575f81556001016144e0565b81516001600160401b0381111561450c5761450c6138ba565b6145208161451a8454613b13565b846144af565b602080601f831160018114614553575f841561453c5750858301515b5f19600386901b1c1916600185901b178555610ac5565b5f85815260208120601f198616915b8281101561458157888601518255948401946001909101908401614562565b508582101561459e57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f602082840312156145be575f80fd5b81518015158114610643575f80fd5b5f82516145de81846020870161369f565b9190910192915050565b60ff828116828216039081111561060457610604613c00565b600181815b8085111561463b57815f190482111561462157614621613c00565b8085161561462e57918102915b93841c9390800290614606565b509250929050565b5f8261465157506001610604565b8161465d57505f610604565b8160018114614673576002811461467d57614699565b6001915050610604565b60ff84111561468e5761468e613c00565b50506001821b610604565b5060208310610133831016604e8410600b84101617156146bc575081810a610604565b6146c68383614601565b805f19048211156146d9576146d9613c00565b029392505050565b5f6106438383614643565b5f8261470657634e487b7160e01b5f52601260045260245ffd5b50049056fe52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a264697066735822122036661baddca68f18b41dcf8cf7fa29a18f12c3f4e83a03ea216404750ed2a29764736f6c6343000819003354656c65706f7274657252656769737472794170703a20696e76616c69642054", +} + +// ERC20TokenRemoteABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenRemoteMetaData.ABI instead. +var ERC20TokenRemoteABI = ERC20TokenRemoteMetaData.ABI + +// ERC20TokenRemoteBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenRemoteMetaData.Bin instead. +var ERC20TokenRemoteBin = ERC20TokenRemoteMetaData.Bin + +// DeployERC20TokenRemote deploys a new Ethereum contract, binding an instance of ERC20TokenRemote to it. +func DeployERC20TokenRemote(auth *bind.TransactOpts, backend bind.ContractBackend, settings TokenRemoteSettings, tokenName string, tokenSymbol string, tokenDecimals uint8) (common.Address, *types.Transaction, *ERC20TokenRemote, error) { + parsed, err := ERC20TokenRemoteMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20TokenRemoteBin), backend, settings, tokenName, tokenSymbol, tokenDecimals) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenRemote{ERC20TokenRemoteCaller: ERC20TokenRemoteCaller{contract: contract}, ERC20TokenRemoteTransactor: ERC20TokenRemoteTransactor{contract: contract}, ERC20TokenRemoteFilterer: ERC20TokenRemoteFilterer{contract: contract}}, nil +} + +// ERC20TokenRemote is an auto generated Go binding around an Ethereum contract. +type ERC20TokenRemote struct { + ERC20TokenRemoteCaller // Read-only binding to the contract + ERC20TokenRemoteTransactor // Write-only binding to the contract + ERC20TokenRemoteFilterer // Log filterer for contract events +} + +// ERC20TokenRemoteCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenRemoteCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenRemoteTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenRemoteTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenRemoteFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenRemoteFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenRemoteSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenRemoteSession struct { + Contract *ERC20TokenRemote // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenRemoteCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenRemoteCallerSession struct { + Contract *ERC20TokenRemoteCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenRemoteTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenRemoteTransactorSession struct { + Contract *ERC20TokenRemoteTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenRemoteRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenRemoteRaw struct { + Contract *ERC20TokenRemote // Generic contract binding to access the raw methods on +} + +// ERC20TokenRemoteCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenRemoteCallerRaw struct { + Contract *ERC20TokenRemoteCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenRemoteTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenRemoteTransactorRaw struct { + Contract *ERC20TokenRemoteTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenRemote creates a new instance of ERC20TokenRemote, bound to a specific deployed contract. +func NewERC20TokenRemote(address common.Address, backend bind.ContractBackend) (*ERC20TokenRemote, error) { + contract, err := bindERC20TokenRemote(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenRemote{ERC20TokenRemoteCaller: ERC20TokenRemoteCaller{contract: contract}, ERC20TokenRemoteTransactor: ERC20TokenRemoteTransactor{contract: contract}, ERC20TokenRemoteFilterer: ERC20TokenRemoteFilterer{contract: contract}}, nil +} + +// NewERC20TokenRemoteCaller creates a new read-only instance of ERC20TokenRemote, bound to a specific deployed contract. +func NewERC20TokenRemoteCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenRemoteCaller, error) { + contract, err := bindERC20TokenRemote(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteCaller{contract: contract}, nil +} + +// NewERC20TokenRemoteTransactor creates a new write-only instance of ERC20TokenRemote, bound to a specific deployed contract. +func NewERC20TokenRemoteTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenRemoteTransactor, error) { + contract, err := bindERC20TokenRemote(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteTransactor{contract: contract}, nil +} + +// NewERC20TokenRemoteFilterer creates a new log filterer instance of ERC20TokenRemote, bound to a specific deployed contract. +func NewERC20TokenRemoteFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenRemoteFilterer, error) { + contract, err := bindERC20TokenRemote(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteFilterer{contract: contract}, nil +} + +// bindERC20TokenRemote binds a generic wrapper to an already deployed contract. +func bindERC20TokenRemote(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenRemoteMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenRemote *ERC20TokenRemoteRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenRemote.Contract.ERC20TokenRemoteCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenRemote *ERC20TokenRemoteRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.ERC20TokenRemoteTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenRemote *ERC20TokenRemoteRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.ERC20TokenRemoteTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenRemote *ERC20TokenRemoteCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenRemote.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.contract.Transact(opts, method, params...) +} + +// ERC20TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x62431a65. +// +// Solidity: function ERC20_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) ERC20TOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "ERC20_TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ERC20TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x62431a65. +// +// Solidity: function ERC20_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) ERC20TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemote.Contract.ERC20TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemote.CallOpts) +} + +// ERC20TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x62431a65. +// +// Solidity: function ERC20_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) ERC20TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemote.Contract.ERC20TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemote.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) MULTIHOPCALLGASPERWORD(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "MULTI_HOP_CALL_GAS_PER_WORD") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _ERC20TokenRemote.Contract.MULTIHOPCALLGASPERWORD(&_ERC20TokenRemote.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _ERC20TokenRemote.Contract.MULTIHOPCALLGASPERWORD(&_ERC20TokenRemote.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) MULTIHOPCALLREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "MULTI_HOP_CALL_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemote.Contract.MULTIHOPCALLREQUIREDGAS(&_ERC20TokenRemote.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemote.Contract.MULTIHOPCALLREQUIREDGAS(&_ERC20TokenRemote.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) MULTIHOPSENDREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "MULTI_HOP_SEND_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemote.Contract.MULTIHOPSENDREQUIREDGAS(&_ERC20TokenRemote.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemote.Contract.MULTIHOPSENDREQUIREDGAS(&_ERC20TokenRemote.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) REGISTERREMOTEREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "REGISTER_REMOTE_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemote.Contract.REGISTERREMOTEREQUIREDGAS(&_ERC20TokenRemote.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemote.Contract.REGISTERREMOTEREQUIREDGAS(&_ERC20TokenRemote.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemote.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenRemote.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemote.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenRemote.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) TOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemote.Contract.TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemote.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemote.Contract.TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemote.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ERC20TokenRemote.Contract.Allowance(&_ERC20TokenRemote.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ERC20TokenRemote.Contract.Allowance(&_ERC20TokenRemote.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ERC20TokenRemote.Contract.BalanceOf(&_ERC20TokenRemote.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ERC20TokenRemote.Contract.BalanceOf(&_ERC20TokenRemote.CallOpts, account) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) CalculateNumWords(opts *bind.CallOpts, payloadSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "calculateNumWords", payloadSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _ERC20TokenRemote.Contract.CalculateNumWords(&_ERC20TokenRemote.CallOpts, payloadSize) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _ERC20TokenRemote.Contract.CalculateNumWords(&_ERC20TokenRemote.CallOpts, payloadSize) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Decimals() (uint8, error) { + return _ERC20TokenRemote.Contract.Decimals(&_ERC20TokenRemote.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) Decimals() (uint8, error) { + return _ERC20TokenRemote.Contract.Decimals(&_ERC20TokenRemote.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenRemote.Contract.GetBlockchainID(&_ERC20TokenRemote.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenRemote.Contract.GetBlockchainID(&_ERC20TokenRemote.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetInitialReserveImbalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getInitialReserveImbalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetInitialReserveImbalance() (*big.Int, error) { + return _ERC20TokenRemote.Contract.GetInitialReserveImbalance(&_ERC20TokenRemote.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetInitialReserveImbalance() (*big.Int, error) { + return _ERC20TokenRemote.Contract.GetInitialReserveImbalance(&_ERC20TokenRemote.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetIsCollateralized(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getIsCollateralized") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetIsCollateralized() (bool, error) { + return _ERC20TokenRemote.Contract.GetIsCollateralized(&_ERC20TokenRemote.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetIsCollateralized() (bool, error) { + return _ERC20TokenRemote.Contract.GetIsCollateralized(&_ERC20TokenRemote.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenRemote.Contract.GetMinTeleporterVersion(&_ERC20TokenRemote.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenRemote.Contract.GetMinTeleporterVersion(&_ERC20TokenRemote.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetMultiplyOnRemote(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getMultiplyOnRemote") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetMultiplyOnRemote() (bool, error) { + return _ERC20TokenRemote.Contract.GetMultiplyOnRemote(&_ERC20TokenRemote.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetMultiplyOnRemote() (bool, error) { + return _ERC20TokenRemote.Contract.GetMultiplyOnRemote(&_ERC20TokenRemote.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetTokenHomeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getTokenHomeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetTokenHomeAddress() (common.Address, error) { + return _ERC20TokenRemote.Contract.GetTokenHomeAddress(&_ERC20TokenRemote.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetTokenHomeAddress() (common.Address, error) { + return _ERC20TokenRemote.Contract.GetTokenHomeAddress(&_ERC20TokenRemote.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetTokenHomeBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getTokenHomeBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _ERC20TokenRemote.Contract.GetTokenHomeBlockchainID(&_ERC20TokenRemote.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _ERC20TokenRemote.Contract.GetTokenHomeBlockchainID(&_ERC20TokenRemote.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) GetTokenMultiplier(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "getTokenMultiplier") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) GetTokenMultiplier() (*big.Int, error) { + return _ERC20TokenRemote.Contract.GetTokenMultiplier(&_ERC20TokenRemote.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) GetTokenMultiplier() (*big.Int, error) { + return _ERC20TokenRemote.Contract.GetTokenMultiplier(&_ERC20TokenRemote.CallOpts) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenRemote.Contract.IsTeleporterAddressPaused(&_ERC20TokenRemote.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenRemote.Contract.IsTeleporterAddressPaused(&_ERC20TokenRemote.CallOpts, teleporterAddress) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Name() (string, error) { + return _ERC20TokenRemote.Contract.Name(&_ERC20TokenRemote.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) Name() (string, error) { + return _ERC20TokenRemote.Contract.Name(&_ERC20TokenRemote.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Owner() (common.Address, error) { + return _ERC20TokenRemote.Contract.Owner(&_ERC20TokenRemote.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) Owner() (common.Address, error) { + return _ERC20TokenRemote.Contract.Owner(&_ERC20TokenRemote.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Symbol() (string, error) { + return _ERC20TokenRemote.Contract.Symbol(&_ERC20TokenRemote.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) Symbol() (string, error) { + return _ERC20TokenRemote.Contract.Symbol(&_ERC20TokenRemote.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemote.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) TotalSupply() (*big.Int, error) { + return _ERC20TokenRemote.Contract.TotalSupply(&_ERC20TokenRemote.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20TokenRemote *ERC20TokenRemoteCallerSession) TotalSupply() (*big.Int, error) { + return _ERC20TokenRemote.Contract.TotalSupply(&_ERC20TokenRemote.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Approve(&_ERC20TokenRemote.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Approve(&_ERC20TokenRemote.TransactOpts, spender, value) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc9fe4ddf. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string tokenName, string tokenSymbol, uint8 tokenDecimals) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) Initialize(opts *bind.TransactOpts, settings TokenRemoteSettings, tokenName string, tokenSymbol string, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "initialize", settings, tokenName, tokenSymbol, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc9fe4ddf. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string tokenName, string tokenSymbol, uint8 tokenDecimals) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Initialize(settings TokenRemoteSettings, tokenName string, tokenSymbol string, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Initialize(&_ERC20TokenRemote.TransactOpts, settings, tokenName, tokenSymbol, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc9fe4ddf. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string tokenName, string tokenSymbol, uint8 tokenDecimals) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) Initialize(settings TokenRemoteSettings, tokenName string, tokenSymbol string, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Initialize(&_ERC20TokenRemote.TransactOpts, settings, tokenName, tokenSymbol, tokenDecimals) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.PauseTeleporterAddress(&_ERC20TokenRemote.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.PauseTeleporterAddress(&_ERC20TokenRemote.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.ReceiveTeleporterMessage(&_ERC20TokenRemote.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.ReceiveTeleporterMessage(&_ERC20TokenRemote.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) RegisterWithHome(opts *bind.TransactOpts, feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "registerWithHome", feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.RegisterWithHome(&_ERC20TokenRemote.TransactOpts, feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.RegisterWithHome(&_ERC20TokenRemote.TransactOpts, feeInfo) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.RenounceOwnership(&_ERC20TokenRemote.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.RenounceOwnership(&_ERC20TokenRemote.TransactOpts) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) Send(opts *bind.TransactOpts, input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "send", input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Send(&_ERC20TokenRemote.TransactOpts, input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Send(&_ERC20TokenRemote.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "sendAndCall", input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.SendAndCall(&_ERC20TokenRemote.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.SendAndCall(&_ERC20TokenRemote.TransactOpts, input, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Transfer(&_ERC20TokenRemote.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.Transfer(&_ERC20TokenRemote.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.TransferFrom(&_ERC20TokenRemote.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.TransferFrom(&_ERC20TokenRemote.TransactOpts, from, to, value) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.TransferOwnership(&_ERC20TokenRemote.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.TransferOwnership(&_ERC20TokenRemote.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.UnpauseTeleporterAddress(&_ERC20TokenRemote.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.UnpauseTeleporterAddress(&_ERC20TokenRemote.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.UpdateMinTeleporterVersion(&_ERC20TokenRemote.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenRemote *ERC20TokenRemoteTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemote.Contract.UpdateMinTeleporterVersion(&_ERC20TokenRemote.TransactOpts, version) +} + +// ERC20TokenRemoteApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteApprovalIterator struct { + Event *ERC20TokenRemoteApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteApproval represents a Approval event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ERC20TokenRemoteApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteApprovalIterator{contract: _ERC20TokenRemote.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteApproval) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseApproval(log types.Log) (*ERC20TokenRemoteApproval, error) { + event := new(ERC20TokenRemoteApproval) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteCallFailedIterator struct { + Event *ERC20TokenRemoteCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteCallFailed represents a CallFailed event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenRemoteCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteCallFailedIterator{contract: _ERC20TokenRemote.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteCallFailed) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseCallFailed(log types.Log) (*ERC20TokenRemoteCallFailed, error) { + event := new(ERC20TokenRemoteCallFailed) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteCallSucceededIterator struct { + Event *ERC20TokenRemoteCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteCallSucceeded represents a CallSucceeded event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenRemoteCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteCallSucceededIterator{contract: _ERC20TokenRemote.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteCallSucceeded) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseCallSucceeded(log types.Log) (*ERC20TokenRemoteCallSucceeded, error) { + event := new(ERC20TokenRemoteCallSucceeded) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteInitializedIterator struct { + Event *ERC20TokenRemoteInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteInitialized represents a Initialized event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterInitialized(opts *bind.FilterOpts) (*ERC20TokenRemoteInitializedIterator, error) { + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ERC20TokenRemoteInitializedIterator{contract: _ERC20TokenRemote.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteInitialized) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteInitialized) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseInitialized(log types.Log) (*ERC20TokenRemoteInitialized, error) { + event := new(ERC20TokenRemoteInitialized) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteMinTeleporterVersionUpdatedIterator struct { + Event *ERC20TokenRemoteMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*ERC20TokenRemoteMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteMinTeleporterVersionUpdatedIterator{contract: _ERC20TokenRemote.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteMinTeleporterVersionUpdated) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*ERC20TokenRemoteMinTeleporterVersionUpdated, error) { + event := new(ERC20TokenRemoteMinTeleporterVersionUpdated) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteOwnershipTransferredIterator struct { + Event *ERC20TokenRemoteOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteOwnershipTransferred represents a OwnershipTransferred event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ERC20TokenRemoteOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteOwnershipTransferredIterator{contract: _ERC20TokenRemote.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteOwnershipTransferred) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseOwnershipTransferred(log types.Log) (*ERC20TokenRemoteOwnershipTransferred, error) { + event := new(ERC20TokenRemoteOwnershipTransferred) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTeleporterAddressPausedIterator struct { + Event *ERC20TokenRemoteTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenRemoteTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteTeleporterAddressPausedIterator{contract: _ERC20TokenRemote.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteTeleporterAddressPaused) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseTeleporterAddressPaused(log types.Log) (*ERC20TokenRemoteTeleporterAddressPaused, error) { + event := new(ERC20TokenRemoteTeleporterAddressPaused) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTeleporterAddressUnpausedIterator struct { + Event *ERC20TokenRemoteTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenRemoteTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteTeleporterAddressUnpausedIterator{contract: _ERC20TokenRemote.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteTeleporterAddressUnpaused) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*ERC20TokenRemoteTeleporterAddressUnpaused, error) { + event := new(ERC20TokenRemoteTeleporterAddressUnpaused) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTokensAndCallSentIterator struct { + Event *ERC20TokenRemoteTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteTokensAndCallSent represents a TokensAndCallSent event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenRemoteTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteTokensAndCallSentIterator{contract: _ERC20TokenRemote.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteTokensAndCallSent) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseTokensAndCallSent(log types.Log) (*ERC20TokenRemoteTokensAndCallSent, error) { + event := new(ERC20TokenRemoteTokensAndCallSent) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTokensSentIterator struct { + Event *ERC20TokenRemoteTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteTokensSent represents a TokensSent event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenRemoteTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteTokensSentIterator{contract: _ERC20TokenRemote.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteTokensSent) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseTokensSent(log types.Log) (*ERC20TokenRemoteTokensSent, error) { + event := new(ERC20TokenRemoteTokensSent) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTokensWithdrawnIterator struct { + Event *ERC20TokenRemoteTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteTokensWithdrawn represents a TokensWithdrawn event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*ERC20TokenRemoteTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteTokensWithdrawnIterator{contract: _ERC20TokenRemote.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteTokensWithdrawn) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseTokensWithdrawn(log types.Log) (*ERC20TokenRemoteTokensWithdrawn, error) { + event := new(ERC20TokenRemoteTokensWithdrawn) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTransferIterator struct { + Event *ERC20TokenRemoteTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteTransfer represents a Transfer event raised by the ERC20TokenRemote contract. +type ERC20TokenRemoteTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ERC20TokenRemoteTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteTransferIterator{contract: _ERC20TokenRemote.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ERC20TokenRemote.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteTransfer) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ERC20TokenRemote *ERC20TokenRemoteFilterer) ParseTransfer(log types.Log) (*ERC20TokenRemoteTransfer, error) { + event := new(ERC20TokenRemoteTransfer) + if err := _ERC20TokenRemote.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemoteUpgradeable/ERC20TokenRemoteUpgradeable.go b/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemoteUpgradeable/ERC20TokenRemoteUpgradeable.go new file mode 100644 index 000000000..e8772df09 --- /dev/null +++ b/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemoteUpgradeable/ERC20TokenRemoteUpgradeable.go @@ -0,0 +1,3044 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokenremoteupgradeable + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// TokenRemoteSettings is an auto generated low-level Go binding around an user-defined struct. +type TokenRemoteSettings struct { + TeleporterRegistryAddress common.Address + TeleporterManager common.Address + MinTeleporterVersion *big.Int + TokenHomeBlockchainID [32]byte + TokenHomeAddress common.Address + TokenHomeDecimals uint8 +} + +// ERC20TokenRemoteUpgradeableMetaData contains all meta data concerning the ERC20TokenRemoteUpgradeable contract. +var ERC20TokenRemoteUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"enumICMInitializable\",\"name\":\"init\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ERC20_TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_GAS_PER_WORD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_SEND_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTER_REMOTE_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"payloadSize\",\"type\":\"uint256\"}],\"name\":\"calculateNumWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInitialReserveImbalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getIsCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMultiplyOnRemote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"tokenHomeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"tokenHomeAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenHomeDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structTokenRemoteSettings\",\"name\":\"settings\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"tokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"tokenDecimals\",\"type\":\"uint8\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"registerWithHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b506040516148ce3803806148ce83398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b6147818061014d5f395ff3fe608060405234801561000f575f80fd5b506004361061021e575f3560e01c806370a082311161012a578063b8a46d02116100b4578063dd62ed3e11610079578063dd62ed3e146104bd578063e0fd9cb8146104d0578063ef793e2a146104d8578063f2fde38b146104e0578063f3f981d8146104f3575f80fd5b8063b8a46d0214610474578063c3cd692714610487578063c868efaa1461048f578063c9fe4ddf146104a2578063d2cc7a70146104b5575f80fd5b80638da5cb5b116100fa5780638da5cb5b146103ee578063909a6ac01461043257806395d89b4114610446578063973142971461044e578063a9059cbb14610461575f80fd5b806370a08231146103a0578063715018a6146103d457806371717c18146103dc5780637ee3779a146103e6575f80fd5b8063313ce567116101ab5780635507f3d11161017b5780635507f3d1146103365780635d16225d146103405780635eb995141461035357806362431a6514610366578063656900381461038d575f80fd5b8063313ce567146102c057806335cac159146102f45780634213cf781461031b5780634511243e14610323575f80fd5b806315beb59f116101f157806315beb59f1461027d57806318160ddd1461028657806323b872dd1461028e578063254ac160146102a15780632b0d8f18146102ab575f80fd5b806302a30c7d1461022257806306fdde031461023f5780630733c8c814610254578063095ea7b31461026a575b5f80fd5b61022a610506565b60405190151581526020015b60405180910390f35b61024761051d565b60405161023691906136ec565b61025c6105dd565b604051908152602001610236565b61022a610278366004613722565b6105f1565b61025c6105dc81565b61025c61060a565b61022a61029c36600461374c565b610625565b61025c6201fbd081565b6102be6102b936600461378a565b61064a565b005b7f9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf626223005460405160ff9091168152602001610236565b61025c7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0081565b61025c61074c565b6102be61033136600461378a565b61075d565b61025c6205302081565b6102be61034e3660046137a5565b61084c565b6102be6103613660046137d4565b61085a565b61025c7f9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf6262230081565b6102be61039b3660046137eb565b61086e565b61025c6103ae36600461378a565b6001600160a01b03165f9081525f8051602061470c833981519152602052604090205490565b6102be610878565b61025c6205573081565b61022a61088b565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b039091168152602001610236565b61025c5f8051602061472c83398151915281565b6102476108a2565b61022a61045c36600461378a565b6108e0565b61022a61046f366004613722565b6108f9565b6102be610482366004613823565b610906565b61041a610acd565b6102be61049d366004613839565b610aea565b6102be6104b03660046139f3565b610ca7565b61025c610db9565b61025c6104cb366004613adc565b610dce565b61025c610e17565b61025c610e2b565b6102be6104ee36600461378a565b610e3f565b61025c6105013660046137d4565b610e79565b5f80610510610e8f565b6006015460ff1692915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0380546060915f8051602061470c8339815191529161055b90613b13565b80601f016020809104026020016040519081016040528092919081815260200182805461058790613b13565b80156105d25780601f106105a9576101008083540402835291602001916105d2565b820191905f5260205f20905b8154815290600101906020018083116105b557829003601f168201915b505050505091505090565b5f806105e7610e8f565b6003015492915050565b5f336105fe818585610eb3565b60019150505b92915050565b5f805f8051602061470c8339815191525b6002015492915050565b5f33610632858285610ec5565b61063d858585610f22565b60019150505b9392505050565b5f8051602061472c833981519152610660610f7f565b6001600160a01b03821661068f5760405162461bcd60e51b815260040161068690613b45565b60405180910390fd5b6106998183610f87565b156106fc5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b6064820152608401610686565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b5f80610756610e8f565b5492915050565b5f8051602061472c833981519152610773610f7f565b6001600160a01b0382166107995760405162461bcd60e51b815260040161068690613b45565b6107a38183610f87565b6108015760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b6064820152608401610686565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b6108568282610fa8565b5050565b610862610f7f565b61086b81611030565b50565b61085682826111c8565b610880611250565b6108895f6112ab565b565b5f80610895610e8f565b6004015460ff1692915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f8051602061470c8339815191529161055b90613b13565b5f5f8051602061472c8339815191526106438184610f87565b5f336105fe818585610f22565b5f61090f610e8f565b6006810154909150610100900460ff161561096c5760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e52656d6f74653a20616c72656164792072656769737465726564006044820152606401610686565b604080516060808201835260058401548252600284015460ff600160a01b820481166020808601918252600160a81b9093048216858701908152865180880188525f808252885188518188015293518516848a01529151909316828601528651808303909501855260809091019095528082019290925291929091610a01906109f79087018761378a565b866020013561131b565b6040805160c0810182526001870154815260028701546001600160a01b031660208083019190915282518084018452939450610ac5939192830191908190610a4b908b018b61378a565b6001600160a01b0316815260209081018690529082526201fbd0908201526040015f5b604051908082528060200260200182016040528015610a97578160200160208202803683370190505b50815260200184604051602001610aae9190613ba7565b604051602081830303815290604052815250611363565b505050505050565b5f80610ad7610e8f565b600201546001600160a01b031692915050565b610af261147e565b5f5f8051602061472c83398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610b5d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b819190613be9565b1015610be85760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b6064820152608401610686565b610bf28133610f87565b15610c585760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b6064820152608401610686565b610c98858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506114c892505050565b50610ca16116df565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610ceb5750825b90505f826001600160401b03166001148015610d065750303b155b905081158015610d14575080155b15610d325760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610d5c57845460ff60401b1916600160401b1785555b610d6889898989611709565b8315610dae57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b5f805f8051602061472c83398151915261061b565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b5f80610e21610e8f565b6001015492915050565b5f80610e35610e8f565b6005015492915050565b610e47611250565b6001600160a01b038116610e7057604051631e4fbdf760e01b81525f6004820152602401610686565b61086b816112ab565b5f6005610e8783601f613c14565b901c92915050565b7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0090565b610ec08383836001611759565b505050565b5f610ed08484610dce565b90505f198114610ca15781811015610f1457604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610686565b610ca184848484035f611759565b6001600160a01b038316610f4b57604051634b637e8f60e11b81525f6004820152602401610686565b6001600160a01b038216610f745760405163ec442f0560e01b81525f6004820152602401610686565b610ec083838361183c565b610889611250565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c75008054600114610fea5760405162461bcd60e51b815260040161068690613c27565b600281555f610ff7610e8f565b905061100284611975565b600181015484350361101d576110188484611a60565b611027565b6110278484611be4565b50600190555050565b5f8051602061472c83398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015611084573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a89190613be9565b60028301549091508184111561111a5760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b6064820152608401610686565b80841161118f5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e006064820152608401610686565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500805460011461120a5760405162461bcd60e51b815260040161068690613c27565b600281555f611217610e8f565b905061122284611daf565b600181015484350361123e576112388484611fe9565b50611248565b61123884846121f8565b600190555050565b336112827f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146108895760405163118cdaa760e01b8152336004820152602401610686565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f815f0361132a57505f610604565b306001600160a01b0384160361135857611346335b3084610ec5565b611351333084610f22565b5080610604565b610643833384612494565b5f8061136d6125f7565b60408401516020015190915015611412576040830151516001600160a01b03166113ef5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b6064820152608401610686565b604083015160208101519051611412916001600160a01b039091169083906126e7565b604051630624488560e41b81526001600160a01b0382169063624488509061143e908690600401613c6b565b6020604051808303815f875af115801561145a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106439190613be9565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008054600119016114c257604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f6114d1610e8f565b9050806001015484146115385760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20696e76616c696420736f7572636520626c6f636044820152681ad8da185a5b88125160ba1b6064820152608401610686565b60028101546001600160a01b038481169116146115aa5760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a20696e76616c6964206f726967696e2073656e646044820152696572206164647265737360b01b6064820152608401610686565b5f828060200190518101906115bf9190613d64565b6006830154909150610100900460ff1615806115e05750600682015460ff16155b156115f75760068201805461ffff19166101011790555b60018151600481111561160c5761160c613b93565b03611643575f816020015180602001905181019061162a9190613dec565b905061163d815f0151826020015161276e565b506116d8565b60028151600481111561165857611658613b93565b03611686575f81602001518060200190518101906116769190613e24565b905061163d8182608001516127bb565b60405162461bcd60e51b815260206004820152602160248201527f546f6b656e52656d6f74653a20696e76616c6964206d657373616765207479706044820152606560f81b6064820152608401610686565b5050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b611711612914565b61171b838361295d565b611726845f8361296f565b7f9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf62622300805460ff191660ff8316179055610ca1565b5f8051602061470c8339815191526001600160a01b0385166117905760405163e602df0560e01b81525f6004820152602401610686565b6001600160a01b0384166117b957604051634a1406b160e11b81525f6004820152602401610686565b6001600160a01b038086165f908152600183016020908152604080832093881683529290522083905581156116d857836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161182d91815260200190565b60405180910390a35050505050565b5f8051602061470c8339815191526001600160a01b0384166118765781816002015f82825461186b9190613c14565b909155506118e69050565b6001600160a01b0384165f90815260208290526040902054828110156118c85760405163391434e360e21b81526001600160a01b03861660048201526024810182905260448101849052606401610686565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b038316611904576002810180548390039055611922565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161196791815260200190565b60405180910390a350505050565b5f611986606083016040840161378a565b6001600160a01b0316036119e85760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e74206164647260448201526265737360e81b6064820152608401610686565b5f8160c0013511611a0b5760405162461bcd60e51b815260040161068690613eee565b8035611a295760405162461bcd60e51b815260040161068690613f32565b5f611a3a604083016020840161378a565b6001600160a01b03160361086b5760405162461bcd60e51b815260040161068690613f7d565b5f611a69610e8f565b9050611a99611a7e604085016020860161378a565b60a0850135611a94610100870160e0880161378a565b6129a0565b5f611abd83611aae608087016060880161378a565b86608001358760a00135612a9d565b6040805180820190915291945091505f9080600181526020016040518060400160405280886040016020810190611af4919061378a565b6001600160a01b0316815260200187815250604051602001611b169190613fda565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92611b969282019080611b6e60808c0160608d0161378a565b6001600160a01b03168152602090810188905290825260c08a0135908201526040015f610a6e565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb528888604051611bd4929190613ffa565b60405180910390a3505050505050565b5f611bed610e8f565b9050611c1a8335611c04604086016020870161378a565b611c15610100870160e0880161378a565b612b60565b5f611c2f83611aae608087016060880161378a565b60408051808201825260038152815160e081018352883581529396509193505f9260208084019282820191611c68918b01908b0161378a565b6001600160a01b03168152602001611c8660608a0160408b0161378a565b6001600160a01b031681526020810188905260a0890135604082015260c08901356060820152608001611cc06101008a0160e08b0161378a565b6001600160a01b03169052604051611d309190602001815181526020808301516001600160a01b0390811691830191909152604080840151821690830152606080840151908301526080808401519083015260a0808401519083015260c092830151169181019190915260e00190565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92611b969282019080611d8860808c0160608d0161378a565b6001600160a01b03168152602090810188905290825262053020908201526040015f610a6e565b8035611dcd5760405162461bcd60e51b815260040161068690613f32565b5f611dde604083016020840161378a565b6001600160a01b031603611e045760405162461bcd60e51b815260040161068690613f7d565b5f611e15606083016040840161378a565b6001600160a01b031603611e805760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420636f6e7460448201526b72616374206164647265737360a01b6064820152608401610686565b5f816080013511611ea35760405162461bcd60e51b815260040161068690613eee565b5f8160a0013511611f045760405162461bcd60e51b815260206004820152602560248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420676173206044820152641b1a5b5a5d60da1b6064820152608401610686565b80608001358160a0013510611f6c5760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a20696e76616c696420726563697069656e742067604482015267185cc81b1a5b5a5d60c21b6064820152608401610686565b5f611f7e610100830160e0840161378a565b6001600160a01b03160361086b5760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f2066616c6c6261636b20726563697060448201526b69656e74206164647265737360a01b6064820152608401610686565b5f611ff2610e8f565b905061201d612007604085016020860161378a565b610140850135611a9460e0870160c0880161378a565b5f612045836120346101208701610100880161378a565b866101200135876101400135612a9d565b6040805180820190915291945091505f908060028152602001604051806101000160405280865f01548152602001306001600160a01b031681526020016120893390565b6001600160a01b031681526020016120a760608a0160408b0161378a565b6001600160a01b03168152602081018890526040016120c960608a018a614099565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a0890135602082015260400161211d6101008a0160e08b0161378a565b6001600160a01b0316905260405161213891906020016140db565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f926121ba92820190806121926101208c016101008d0161378a565b6001600160a01b03168152602090810188905290825260808a0135908201526040015f610a6e565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168888604051611bd49291906141e2565b5f612201610e8f565b90506122288335612218604086016020870161378a565b611c1560e0870160c0880161378a565b5f61223f836120346101208701610100880161378a565b6040805180820190915291945091505f90806004815260200160405180610160016040528061226b3390565b6001600160a01b03168152602001885f01358152602001886020016020810190612295919061378a565b6001600160a01b031681526020016122b360608a0160408b0161378a565b6001600160a01b03168152602081018890526040016122d560608a018a614099565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a089013560208201526040016123296101008a0160e08b0161378a565b6001600160a01b031681526080890135602082015260400161235160e08a0160c08b0161378a565b6001600160a01b031681526101408901356020918201526040516123769291016142f0565b60408051601f19818403018152919052905290505f6105dc6123a561239e6060890189614099565b9050610e79565b6123af91906143cd565b6123bc9062055730613c14565b6040805160c0810182526001870154815260028701546001600160a01b03166020820152815180830183529293505f9261244592820190806124066101208d016101008e0161378a565b6001600160a01b031681526020908101899052908252818101869052604080515f815280830182528184015251606090920191610aae91889101613ba7565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b1689896040516124839291906141e2565b60405180910390a350505050505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa1580156124da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124fe9190613be9565b90506125156001600160a01b038616853086612bfe565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015612559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061257d9190613be9565b90508181116125e35760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610686565b6125ed82826143e4565b9695505050505050565b5f8051602061472c83398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612651573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267591906143f7565b90506126818282610f87565b156106045760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b6064820152608401610686565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015612734573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127589190613be9565b9050610ca184846127698585613c14565b612c65565b816001600160a01b03167f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b826040516127a991815260200190565b60405180910390a26108568282612cf4565b6127c53082612cf4565b6127d430836060015183610eb3565b5f825f01518360200151846040015130858760a001516040516024016127ff96959493929190614412565b60408051601f198184030181529190526020810180516001600160e01b03166394395edd60e01b17905260c084015160608501519192505f91612843919084612d28565b90505f612854308660600151610dce565b90506128653086606001515f610eb3565b81156128b75784606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4856040516128aa91815260200190565b60405180910390a26128ff565b84606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0856040516128f691815260200190565b60405180910390a25b80156116d8576116d8308660e0015183610f22565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661088957604051631afcd79f60e31b815260040160405180910390fd5b612965612914565b6108568282612d3d565b612977612914565b61298d835f015184602001518560400151612d8d565b612995612da8565b610ec0838383612db8565b5f6129a9610e8f565b60028101549091506001600160a01b038581169116146129db5760405162461bcd60e51b815260040161068690614452565b8215612a355760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f207365636f6e646172792060448201526266656560e81b6064820152608401610686565b6001600160a01b03821615610ca15760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f206d756c74692d686f702060448201526766616c6c6261636b60c01b6064820152608401610686565b5f805f612aa8610e8f565b9050612ab3876130dc565b9650612abf868661131b565b60038201546004830154919650612ad99160ff16866130f4565b60038201546004830154612af1919060ff168a6130f4565b11612b535760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a20696e73756666696369656e7420746f6b656e7360448201526b103a37903a3930b739b332b960a11b6064820152608401610686565b5094959294509192505050565b5f612b69610e8f565b80549091508403612b9c57306001600160a01b03841603612b9c5760405162461bcd60e51b815260040161068690614452565b6001600160a01b038216610ca15760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f206d756c74692d686f702066616c6c6044820152636261636b60e01b6064820152608401610686565b6040516001600160a01b038481166024830152838116604483015260648201839052610ca19186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613101565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612cb68482613162565b610ca1576040516001600160a01b0384811660248301525f6044830152612cea91869182169063095ea7b390606401612c33565b610ca18482613101565b6001600160a01b038216612d1d5760405163ec442f0560e01b81525f6004820152602401610686565b6108565f838361183c565b5f612d35845f8585613203565b949350505050565b612d45612914565b5f8051602061470c8339815191527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03612d7e84826144f3565b5060048101610ca183826144f3565b612d95612914565b612d9f83826132d3565b610ec0826132f5565b612db0612914565b610889613306565b612dc0612914565b5f612dc9610e8f565b90506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e0e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e329190613be9565b81556060840151612e985760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d6520626c6f60448201526918dad8da185a5b88125160b21b6064820152608401610686565b8054606085015103612f125760405162461bcd60e51b815260206004820152603b60248201527f546f6b656e52656d6f74653a2063616e6e6f74206465706c6f7920746f20736160448201527f6d6520626c6f636b636861696e20617320746f6b656e20686f6d6500000000006064820152608401610686565b60808401516001600160a01b0316612f785760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d65206164646044820152637265737360e01b6064820152608401610686565b60128460a0015160ff161115612fe25760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20746f6b656e20686f6d6520646563696d616c73604482015268040e8dede40d0d2ced60bb1b6064820152608401610686565b60128260ff1611156130425760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a20746f6b656e20646563696d616c7320746f6f206044820152630d0d2ced60e31b6064820152608401610686565b60608401516001820155608084015160028201805460058401869055600684018054871560ff1990911617905560a08701516001600160a01b039093166001600160a81b031990911617600160a01b60ff808516919091029190911760ff60a81b1916600160a81b918616919091021790556130be908361332d565b60048301805460ff1916911515919091179055600390910155505050565b5f6130e63361133f565b6130f03383613377565b5090565b5f612d358484845f6133ab565b5f6131156001600160a01b038416836133d2565b905080515f1415801561313957508080602001905181019061313791906145ae565b155b15610ec057604051635274afe760e01b81526001600160a01b0384166004820152602401610686565b5f805f846001600160a01b03168460405161317d91906145cd565b5f604051808303815f865af19150503d805f81146131b6576040519150601f19603f3d011682016040523d82523d5f602084013e6131bb565b606091505b50915091508180156131e55750805115806131e55750808060200190518101906131e591906145ae565b80156131fa57505f856001600160a01b03163b115b95945050505050565b5f845a10156132545760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e742067617300000000006044820152606401610686565b834710156132a45760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c75650000006044820152606401610686565b826001600160a01b03163b5f036132bc57505f612d35565b5f805f84516020860188888bf19695505050505050565b6132db612914565b6132e36133df565b6132eb6133ef565b61085682826133f7565b6132fd612914565b61086b8161357b565b5f7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500611702565b5f8060ff8085169084161181816133505761334885876145e8565b60ff1661335e565b61335a86866145e8565b60ff165b61336990600a6146e1565b9350909150505b9250929050565b6001600160a01b0382166133a057604051634b637e8f60e11b81525f6004820152602401610686565b610856825f8361183c565b5f811515841515036133c8576133c185846143cd565b9050612d35565b6131fa85846146ec565b606061064383835f613583565b6133e7612914565b610889613612565b610889612914565b6133ff612914565b6001600160a01b03821661347b5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f7274657220726567697374727920616464726573730000000000000000006064820152608401610686565b5f5f8051602061472c83398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134f19190613be9565b116135595760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b6064820152608401610686565b81546001600160a01b0319166001600160a01b038216178255610ca183611030565b610e47612914565b6060814710156135a85760405163cd78605960e01b8152306004820152602401610686565b5f80856001600160a01b031684866040516135c391906145cd565b5f6040518083038185875af1925050503d805f81146135fd576040519150601f19603f3d011682016040523d82523d5f602084013e613602565b606091505b50915091506125ed86838361361a565b6116df612914565b60608261362f5761362a82613676565b610643565b815115801561364657506001600160a01b0384163b155b1561366f57604051639996b31560e01b81526001600160a01b0385166004820152602401610686565b5080610643565b8051156136865780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f5b838110156136b95781810151838201526020016136a1565b50505f910152565b5f81518084526136d881602086016020860161369f565b601f01601f19169290920160200192915050565b602081525f61064360208301846136c1565b6001600160a01b038116811461086b575f80fd5b803561371d816136fe565b919050565b5f8060408385031215613733575f80fd5b823561373e816136fe565b946020939093013593505050565b5f805f6060848603121561375e575f80fd5b8335613769816136fe565b92506020840135613779816136fe565b929592945050506040919091013590565b5f6020828403121561379a575f80fd5b8135610643816136fe565b5f808284036101208112156137b8575f80fd5b610100808212156137c7575f80fd5b9395938601359450505050565b5f602082840312156137e4575f80fd5b5035919050565b5f80604083850312156137fc575f80fd5b82356001600160401b03811115613811575f80fd5b8301610160818603121561373e575f80fd5b5f60408284031215613833575f80fd5b50919050565b5f805f806060858703121561384c575f80fd5b84359350602085013561385e816136fe565b925060408501356001600160401b0380821115613879575f80fd5b818701915087601f83011261388c575f80fd5b81358181111561389a575f80fd5b8860208285010111156138ab575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b03811182821017156138f0576138f06138ba565b60405290565b604080519081016001600160401b03811182821017156138f0576138f06138ba565b60405161010081016001600160401b03811182821017156138f0576138f06138ba565b604051601f8201601f191681016001600160401b0381118282101715613963576139636138ba565b604052919050565b803560ff8116811461371d575f80fd5b5f6001600160401b03821115613993576139936138ba565b50601f01601f191660200190565b5f82601f8301126139b0575f80fd5b81356139c36139be8261397b565b61393b565b8181528460208386010111156139d7575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80848603610120811215613a08575f80fd5b60c0811215613a15575f80fd5b50613a1e6138ce565b8535613a29816136fe565b81526020860135613a39816136fe565b8060208301525060408601356040820152606086013560608201526080860135613a62816136fe565b6080820152613a7360a0870161396b565b60a0820152935060c08501356001600160401b0380821115613a93575f80fd5b613a9f888389016139a1565b945060e0870135915080821115613ab4575f80fd5b50613ac1878288016139a1565b925050613ad1610100860161396b565b905092959194509250565b5f8060408385031215613aed575f80fd5b8235613af8816136fe565b91506020830135613b08816136fe565b809150509250929050565b600181811c90821680613b2757607f821691505b60208210810361383357634e487b7160e01b5f52602260045260245ffd5b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b634e487b7160e01b5f52602160045260245ffd5b602081525f825160058110613bca57634e487b7160e01b5f52602160045260245ffd5b806020840152506020830151604080840152612d3560608401826136c1565b5f60208284031215613bf9575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561060457610604613c00565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b80841015613cf857845183168252938501936001939093019290850190613cd6565b5060a0880151878203601f190160e08901529450613d1681866136c1565b98975050505050505050565b5f82601f830112613d31575f80fd5b8151613d3f6139be8261397b565b818152846020838601011115613d53575f80fd5b612d3582602083016020870161369f565b5f60208284031215613d74575f80fd5b81516001600160401b0380821115613d8a575f80fd5b9083019060408286031215613d9d575f80fd5b613da56138f6565b825160058110613db3575f80fd5b8152602083015182811115613dc6575f80fd5b613dd287828601613d22565b60208301525095945050505050565b805161371d816136fe565b5f60408284031215613dfc575f80fd5b613e046138f6565b8251613e0f816136fe565b81526020928301519281019290925250919050565b5f60208284031215613e34575f80fd5b81516001600160401b0380821115613e4a575f80fd5b908301906101008286031215613e5e575f80fd5b613e66613918565b82518152613e7660208401613de1565b6020820152613e8760408401613de1565b6040820152613e9860608401613de1565b60608201526080830151608082015260a083015182811115613eb8575f80fd5b613ec487828601613d22565b60a08301525060c083015160c0820152613ee060e08401613de1565b60e082015295945050505050565b60208082526024908201527f546f6b656e52656d6f74653a207a65726f20726571756972656420676173206c6040820152631a5b5a5d60e21b606082015260800190565b6020808252602b908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20626c60408201526a1bd8dad8da185a5b88125160aa1b606082015260800190565b60208082526037908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20746f60408201527f6b656e207472616e736665727265722061646472657373000000000000000000606082015260800190565b81516001600160a01b031681526020808301519082015260408101610604565b8235815261012081016020840135614011816136fe565b6001600160a01b039081166020840152604085013590614030826136fe565b16604083015261404260608501613712565b6001600160a01b0381166060840152506080840135608083015260a084013560a083015260c084013560c083015261407c60e08501613712565b6001600160a01b031660e083015261010090910191909152919050565b5f808335601e198436030181126140ae575f80fd5b8301803591506001600160401b038211156140c7575f80fd5b602001915036819003821315613370575f80fd5b60208152815160208201525f602083015160018060a01b0380821660408501528060408601511660608501525050606083015161412360808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c085015261414a6101208501836136c1565b915060c085015160e085015260e085015161416f828601826001600160a01b03169052565b5090949350505050565b5f808335601e1984360301811261418e575f80fd5b83016020810192503590506001600160401b038111156141ac575f80fd5b803603821315613370575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60408152823560408201525f6141fa60208501613712565b6001600160a01b0316606083015261421460408501613712565b6001600160a01b0316608083015261422f6060850185614179565b6101608060a08601526142476101a0860183856141ba565b9250608087013560c086015260a087013560e086015261426960c08801613712565b9150610100614282818701846001600160a01b03169052565b61428e60e08901613712565b92506101206142a7818801856001600160a01b03169052565b6142b2828a01613712565b935061014091506142cd828801856001600160a01b03169052565b880135918601919091529095013561018084015260209092019290925292915050565b6020815261430a6020820183516001600160a01b03169052565b602082015160408201525f604083015161432f60608401826001600160a01b03169052565b5060608301516001600160a01b038116608084015250608083015160a083015260a08301516101608060c085015261436b6101808501836136c1565b915060c085015160e085015260e0850151610100614393818701836001600160a01b03169052565b8601516101208681019190915286015190506101406143bc818701836001600160a01b03169052565b959095015193019290925250919050565b808202811582820484141761060457610604613c00565b8181038181111561060457610604613c00565b5f60208284031215614407575f80fd5b8151610643816136fe565b8681526001600160a01b0386811660208301528581166040830152841660608201526080810183905260c060a082018190525f90613d16908301846136c1565b6020808252603a908201527f546f6b656e52656d6f74653a20696e76616c69642064657374696e6174696f6e60408201527f20746f6b656e207472616e736665727265722061646472657373000000000000606082015260800190565b601f821115610ec057805f5260205f20601f840160051c810160208510156144d45750805b601f840160051c820191505b818110156116d8575f81556001016144e0565b81516001600160401b0381111561450c5761450c6138ba565b6145208161451a8454613b13565b846144af565b602080601f831160018114614553575f841561453c5750858301515b5f19600386901b1c1916600185901b178555610ac5565b5f85815260208120601f198616915b8281101561458157888601518255948401946001909101908401614562565b508582101561459e57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f602082840312156145be575f80fd5b81518015158114610643575f80fd5b5f82516145de81846020870161369f565b9190910192915050565b60ff828116828216039081111561060457610604613c00565b600181815b8085111561463b57815f190482111561462157614621613c00565b8085161561462e57918102915b93841c9390800290614606565b509250929050565b5f8261465157506001610604565b8161465d57505f610604565b8160018114614673576002811461467d57614699565b6001915050610604565b60ff84111561468e5761468e613c00565b50506001821b610604565b5060208310610133831016604e8410600b84101617156146bc575081810a610604565b6146c68383614601565b805f19048211156146d9576146d9613c00565b029392505050565b5f6106438383614643565b5f8261470657634e487b7160e01b5f52601260045260245ffd5b50049056fe52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a2646970667358221220fbb1f0247c2178adef12b1736f8997844e3a10ae5f5a16d470a27a3eb4924b3f64736f6c63430008190033", +} + +// ERC20TokenRemoteUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenRemoteUpgradeableMetaData.ABI instead. +var ERC20TokenRemoteUpgradeableABI = ERC20TokenRemoteUpgradeableMetaData.ABI + +// ERC20TokenRemoteUpgradeableBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenRemoteUpgradeableMetaData.Bin instead. +var ERC20TokenRemoteUpgradeableBin = ERC20TokenRemoteUpgradeableMetaData.Bin + +// DeployERC20TokenRemoteUpgradeable deploys a new Ethereum contract, binding an instance of ERC20TokenRemoteUpgradeable to it. +func DeployERC20TokenRemoteUpgradeable(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *ERC20TokenRemoteUpgradeable, error) { + parsed, err := ERC20TokenRemoteUpgradeableMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20TokenRemoteUpgradeableBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenRemoteUpgradeable{ERC20TokenRemoteUpgradeableCaller: ERC20TokenRemoteUpgradeableCaller{contract: contract}, ERC20TokenRemoteUpgradeableTransactor: ERC20TokenRemoteUpgradeableTransactor{contract: contract}, ERC20TokenRemoteUpgradeableFilterer: ERC20TokenRemoteUpgradeableFilterer{contract: contract}}, nil +} + +// ERC20TokenRemoteUpgradeable is an auto generated Go binding around an Ethereum contract. +type ERC20TokenRemoteUpgradeable struct { + ERC20TokenRemoteUpgradeableCaller // Read-only binding to the contract + ERC20TokenRemoteUpgradeableTransactor // Write-only binding to the contract + ERC20TokenRemoteUpgradeableFilterer // Log filterer for contract events +} + +// ERC20TokenRemoteUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenRemoteUpgradeableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenRemoteUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenRemoteUpgradeableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenRemoteUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenRemoteUpgradeableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenRemoteUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenRemoteUpgradeableSession struct { + Contract *ERC20TokenRemoteUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenRemoteUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenRemoteUpgradeableCallerSession struct { + Contract *ERC20TokenRemoteUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenRemoteUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenRemoteUpgradeableTransactorSession struct { + Contract *ERC20TokenRemoteUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenRemoteUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenRemoteUpgradeableRaw struct { + Contract *ERC20TokenRemoteUpgradeable // Generic contract binding to access the raw methods on +} + +// ERC20TokenRemoteUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenRemoteUpgradeableCallerRaw struct { + Contract *ERC20TokenRemoteUpgradeableCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenRemoteUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenRemoteUpgradeableTransactorRaw struct { + Contract *ERC20TokenRemoteUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenRemoteUpgradeable creates a new instance of ERC20TokenRemoteUpgradeable, bound to a specific deployed contract. +func NewERC20TokenRemoteUpgradeable(address common.Address, backend bind.ContractBackend) (*ERC20TokenRemoteUpgradeable, error) { + contract, err := bindERC20TokenRemoteUpgradeable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeable{ERC20TokenRemoteUpgradeableCaller: ERC20TokenRemoteUpgradeableCaller{contract: contract}, ERC20TokenRemoteUpgradeableTransactor: ERC20TokenRemoteUpgradeableTransactor{contract: contract}, ERC20TokenRemoteUpgradeableFilterer: ERC20TokenRemoteUpgradeableFilterer{contract: contract}}, nil +} + +// NewERC20TokenRemoteUpgradeableCaller creates a new read-only instance of ERC20TokenRemoteUpgradeable, bound to a specific deployed contract. +func NewERC20TokenRemoteUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenRemoteUpgradeableCaller, error) { + contract, err := bindERC20TokenRemoteUpgradeable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableCaller{contract: contract}, nil +} + +// NewERC20TokenRemoteUpgradeableTransactor creates a new write-only instance of ERC20TokenRemoteUpgradeable, bound to a specific deployed contract. +func NewERC20TokenRemoteUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenRemoteUpgradeableTransactor, error) { + contract, err := bindERC20TokenRemoteUpgradeable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableTransactor{contract: contract}, nil +} + +// NewERC20TokenRemoteUpgradeableFilterer creates a new log filterer instance of ERC20TokenRemoteUpgradeable, bound to a specific deployed contract. +func NewERC20TokenRemoteUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenRemoteUpgradeableFilterer, error) { + contract, err := bindERC20TokenRemoteUpgradeable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableFilterer{contract: contract}, nil +} + +// bindERC20TokenRemoteUpgradeable binds a generic wrapper to an already deployed contract. +func bindERC20TokenRemoteUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenRemoteUpgradeableMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenRemoteUpgradeable.Contract.ERC20TokenRemoteUpgradeableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.ERC20TokenRemoteUpgradeableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.ERC20TokenRemoteUpgradeableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenRemoteUpgradeable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.contract.Transact(opts, method, params...) +} + +// ERC20TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x62431a65. +// +// Solidity: function ERC20_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) ERC20TOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "ERC20_TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ERC20TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x62431a65. +// +// Solidity: function ERC20_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) ERC20TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.ERC20TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// ERC20TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x62431a65. +// +// Solidity: function ERC20_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) ERC20TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.ERC20TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) MULTIHOPCALLGASPERWORD(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "MULTI_HOP_CALL_GAS_PER_WORD") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.MULTIHOPCALLGASPERWORD(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.MULTIHOPCALLGASPERWORD(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) MULTIHOPCALLREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "MULTI_HOP_CALL_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.MULTIHOPCALLREQUIREDGAS(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.MULTIHOPCALLREQUIREDGAS(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) MULTIHOPSENDREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "MULTI_HOP_SEND_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.MULTIHOPSENDREQUIREDGAS(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.MULTIHOPSENDREQUIREDGAS(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) REGISTERREMOTEREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "REGISTER_REMOTE_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.REGISTERREMOTEREQUIREDGAS(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.REGISTERREMOTEREQUIREDGAS(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) TOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TOKENREMOTESTORAGELOCATION(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Allowance(&_ERC20TokenRemoteUpgradeable.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Allowance(&_ERC20TokenRemoteUpgradeable.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.BalanceOf(&_ERC20TokenRemoteUpgradeable.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.BalanceOf(&_ERC20TokenRemoteUpgradeable.CallOpts, account) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) CalculateNumWords(opts *bind.CallOpts, payloadSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "calculateNumWords", payloadSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.CalculateNumWords(&_ERC20TokenRemoteUpgradeable.CallOpts, payloadSize) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.CalculateNumWords(&_ERC20TokenRemoteUpgradeable.CallOpts, payloadSize) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Decimals() (uint8, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Decimals(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) Decimals() (uint8, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Decimals(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetBlockchainID(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetBlockchainID() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetBlockchainID(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetInitialReserveImbalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getInitialReserveImbalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetInitialReserveImbalance() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetInitialReserveImbalance(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetInitialReserveImbalance() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetInitialReserveImbalance(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetIsCollateralized(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getIsCollateralized") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetIsCollateralized() (bool, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetIsCollateralized(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetIsCollateralized() (bool, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetIsCollateralized(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetMinTeleporterVersion(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetMinTeleporterVersion(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetMultiplyOnRemote(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getMultiplyOnRemote") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetMultiplyOnRemote() (bool, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetMultiplyOnRemote(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetMultiplyOnRemote() (bool, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetMultiplyOnRemote(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetTokenHomeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getTokenHomeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetTokenHomeAddress() (common.Address, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetTokenHomeAddress(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetTokenHomeAddress() (common.Address, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetTokenHomeAddress(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetTokenHomeBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getTokenHomeBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetTokenHomeBlockchainID(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetTokenHomeBlockchainID(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) GetTokenMultiplier(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "getTokenMultiplier") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) GetTokenMultiplier() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetTokenMultiplier(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) GetTokenMultiplier() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.GetTokenMultiplier(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenRemoteUpgradeable.Contract.IsTeleporterAddressPaused(&_ERC20TokenRemoteUpgradeable.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _ERC20TokenRemoteUpgradeable.Contract.IsTeleporterAddressPaused(&_ERC20TokenRemoteUpgradeable.CallOpts, teleporterAddress) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Name() (string, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Name(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) Name() (string, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Name(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Owner() (common.Address, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Owner(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) Owner() (common.Address, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Owner(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Symbol() (string, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Symbol(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) Symbol() (string, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Symbol(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenRemoteUpgradeable.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) TotalSupply() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TotalSupply(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableCallerSession) TotalSupply() (*big.Int, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TotalSupply(&_ERC20TokenRemoteUpgradeable.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Approve(&_ERC20TokenRemoteUpgradeable.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Approve(&_ERC20TokenRemoteUpgradeable.TransactOpts, spender, value) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc9fe4ddf. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string tokenName, string tokenSymbol, uint8 tokenDecimals) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) Initialize(opts *bind.TransactOpts, settings TokenRemoteSettings, tokenName string, tokenSymbol string, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "initialize", settings, tokenName, tokenSymbol, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc9fe4ddf. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string tokenName, string tokenSymbol, uint8 tokenDecimals) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Initialize(settings TokenRemoteSettings, tokenName string, tokenSymbol string, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Initialize(&_ERC20TokenRemoteUpgradeable.TransactOpts, settings, tokenName, tokenSymbol, tokenDecimals) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc9fe4ddf. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string tokenName, string tokenSymbol, uint8 tokenDecimals) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) Initialize(settings TokenRemoteSettings, tokenName string, tokenSymbol string, tokenDecimals uint8) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Initialize(&_ERC20TokenRemoteUpgradeable.TransactOpts, settings, tokenName, tokenSymbol, tokenDecimals) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.PauseTeleporterAddress(&_ERC20TokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.PauseTeleporterAddress(&_ERC20TokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.ReceiveTeleporterMessage(&_ERC20TokenRemoteUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.ReceiveTeleporterMessage(&_ERC20TokenRemoteUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) RegisterWithHome(opts *bind.TransactOpts, feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "registerWithHome", feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.RegisterWithHome(&_ERC20TokenRemoteUpgradeable.TransactOpts, feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.RegisterWithHome(&_ERC20TokenRemoteUpgradeable.TransactOpts, feeInfo) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.RenounceOwnership(&_ERC20TokenRemoteUpgradeable.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.RenounceOwnership(&_ERC20TokenRemoteUpgradeable.TransactOpts) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) Send(opts *bind.TransactOpts, input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "send", input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Send(&_ERC20TokenRemoteUpgradeable.TransactOpts, input, amount) +} + +// Send is a paid mutator transaction binding the contract method 0x5d16225d. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) Send(input SendTokensInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Send(&_ERC20TokenRemoteUpgradeable.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "sendAndCall", input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.SendAndCall(&_ERC20TokenRemoteUpgradeable.TransactOpts, input, amount) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x65690038. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) SendAndCall(input SendAndCallInput, amount *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.SendAndCall(&_ERC20TokenRemoteUpgradeable.TransactOpts, input, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Transfer(&_ERC20TokenRemoteUpgradeable.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.Transfer(&_ERC20TokenRemoteUpgradeable.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TransferFrom(&_ERC20TokenRemoteUpgradeable.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TransferFrom(&_ERC20TokenRemoteUpgradeable.TransactOpts, from, to, value) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TransferOwnership(&_ERC20TokenRemoteUpgradeable.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.TransferOwnership(&_ERC20TokenRemoteUpgradeable.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.UnpauseTeleporterAddress(&_ERC20TokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.UnpauseTeleporterAddress(&_ERC20TokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.UpdateMinTeleporterVersion(&_ERC20TokenRemoteUpgradeable.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _ERC20TokenRemoteUpgradeable.Contract.UpdateMinTeleporterVersion(&_ERC20TokenRemoteUpgradeable.TransactOpts, version) +} + +// ERC20TokenRemoteUpgradeableApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableApprovalIterator struct { + Event *ERC20TokenRemoteUpgradeableApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableApproval represents a Approval event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ERC20TokenRemoteUpgradeableApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableApprovalIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableApproval) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseApproval(log types.Log) (*ERC20TokenRemoteUpgradeableApproval, error) { + event := new(ERC20TokenRemoteUpgradeableApproval) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableCallFailedIterator struct { + Event *ERC20TokenRemoteUpgradeableCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableCallFailed represents a CallFailed event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenRemoteUpgradeableCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableCallFailedIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableCallFailed) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseCallFailed(log types.Log) (*ERC20TokenRemoteUpgradeableCallFailed, error) { + event := new(ERC20TokenRemoteUpgradeableCallFailed) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableCallSucceededIterator struct { + Event *ERC20TokenRemoteUpgradeableCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableCallSucceeded represents a CallSucceeded event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*ERC20TokenRemoteUpgradeableCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableCallSucceededIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableCallSucceeded) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseCallSucceeded(log types.Log) (*ERC20TokenRemoteUpgradeableCallSucceeded, error) { + event := new(ERC20TokenRemoteUpgradeableCallSucceeded) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableInitializedIterator struct { + Event *ERC20TokenRemoteUpgradeableInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableInitialized represents a Initialized event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*ERC20TokenRemoteUpgradeableInitializedIterator, error) { + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableInitializedIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableInitialized) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableInitialized) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseInitialized(log types.Log) (*ERC20TokenRemoteUpgradeableInitialized, error) { + event := new(ERC20TokenRemoteUpgradeableInitialized) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator struct { + Event *ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated, error) { + event := new(ERC20TokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableOwnershipTransferredIterator struct { + Event *ERC20TokenRemoteUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ERC20TokenRemoteUpgradeableOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableOwnershipTransferredIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableOwnershipTransferred) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*ERC20TokenRemoteUpgradeableOwnershipTransferred, error) { + event := new(ERC20TokenRemoteUpgradeableOwnershipTransferred) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTeleporterAddressPausedIterator struct { + Event *ERC20TokenRemoteUpgradeableTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenRemoteUpgradeableTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableTeleporterAddressPausedIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableTeleporterAddressPaused) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseTeleporterAddressPaused(log types.Log) (*ERC20TokenRemoteUpgradeableTeleporterAddressPaused, error) { + event := new(ERC20TokenRemoteUpgradeableTeleporterAddressPaused) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTeleporterAddressUnpausedIterator struct { + Event *ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*ERC20TokenRemoteUpgradeableTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableTeleporterAddressUnpausedIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused, error) { + event := new(ERC20TokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTokensAndCallSentIterator struct { + Event *ERC20TokenRemoteUpgradeableTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableTokensAndCallSent represents a TokensAndCallSent event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenRemoteUpgradeableTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableTokensAndCallSentIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableTokensAndCallSent) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseTokensAndCallSent(log types.Log) (*ERC20TokenRemoteUpgradeableTokensAndCallSent, error) { + event := new(ERC20TokenRemoteUpgradeableTokensAndCallSent) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTokensSentIterator struct { + Event *ERC20TokenRemoteUpgradeableTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableTokensSent represents a TokensSent event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*ERC20TokenRemoteUpgradeableTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableTokensSentIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableTokensSent) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseTokensSent(log types.Log) (*ERC20TokenRemoteUpgradeableTokensSent, error) { + event := new(ERC20TokenRemoteUpgradeableTokensSent) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTokensWithdrawnIterator struct { + Event *ERC20TokenRemoteUpgradeableTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableTokensWithdrawn represents a TokensWithdrawn event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*ERC20TokenRemoteUpgradeableTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableTokensWithdrawnIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableTokensWithdrawn) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseTokensWithdrawn(log types.Log) (*ERC20TokenRemoteUpgradeableTokensWithdrawn, error) { + event := new(ERC20TokenRemoteUpgradeableTokensWithdrawn) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenRemoteUpgradeableTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTransferIterator struct { + Event *ERC20TokenRemoteUpgradeableTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenRemoteUpgradeableTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenRemoteUpgradeableTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenRemoteUpgradeableTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenRemoteUpgradeableTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenRemoteUpgradeableTransfer represents a Transfer event raised by the ERC20TokenRemoteUpgradeable contract. +type ERC20TokenRemoteUpgradeableTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ERC20TokenRemoteUpgradeableTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &ERC20TokenRemoteUpgradeableTransferIterator{contract: _ERC20TokenRemoteUpgradeable.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ERC20TokenRemoteUpgradeableTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ERC20TokenRemoteUpgradeable.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenRemoteUpgradeableTransfer) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ERC20TokenRemoteUpgradeable *ERC20TokenRemoteUpgradeableFilterer) ParseTransfer(log types.Log) (*ERC20TokenRemoteUpgradeableTransfer, error) { + event := new(ERC20TokenRemoteUpgradeableTransfer) + if err := _ERC20TokenRemoteUpgradeable.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenRemote/NativeTokenRemote/NativeTokenRemote.go b/abi-bindings/go/ictt/TokenRemote/NativeTokenRemote/NativeTokenRemote.go new file mode 100644 index 000000000..9dd72af0a --- /dev/null +++ b/abi-bindings/go/ictt/TokenRemote/NativeTokenRemote/NativeTokenRemote.go @@ -0,0 +1,3770 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokenremote + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// TokenRemoteSettings is an auto generated low-level Go binding around an user-defined struct. +type TokenRemoteSettings struct { + TeleporterRegistryAddress common.Address + TeleporterManager common.Address + MinTeleporterVersion *big.Int + TokenHomeBlockchainID [32]byte + TokenHomeAddress common.Address + TokenHomeDecimals uint8 +} + +// NativeTokenRemoteMetaData contains all meta data concerning the NativeTokenRemote contract. +var NativeTokenRemoteMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"tokenHomeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"tokenHomeAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenHomeDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structTokenRemoteSettings\",\"name\":\"settings\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"nativeAssetSymbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"initialReserveImbalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"burnedFeesReportingRewardPercentage\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feesBurned\",\"type\":\"uint256\"}],\"name\":\"ReportBurnedTxFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"BURNED_FOR_TRANSFER_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BURNED_TX_FEES_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"HOME_CHAIN_BURN_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_GAS_PER_WORD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_SEND_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NATIVE_MINTER\",\"outputs\":[{\"internalType\":\"contractINativeMinter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NATIVE_TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTER_REMOTE_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"payloadSize\",\"type\":\"uint256\"}],\"name\":\"calculateNumWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInitialReserveImbalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getIsCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMultiplyOnRemote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalMinted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"tokenHomeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"tokenHomeAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenHomeDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structTokenRemoteSettings\",\"name\":\"settings\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"nativeAssetSymbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"initialReserveImbalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"burnedFeesReportingRewardPercentage\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"registerWithHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"}],\"name\":\"reportBurnedTxFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalNativeAssetSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561000f575f80fd5b50604051615fee380380615fee83398101604081905261002e91610cb3565b61003a84848484610046565b50505050610ff4565b50565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f8115801561008f5750825b90505f826001600160401b031660011480156100aa5750303b155b9050811580156100b8575080155b156100d65760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561010457845460ff60401b1916680100000000000000001785555b61011089898989610161565b831561015657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6101696101fc565b815f036101d75760405162461bcd60e51b815260206004820152603160248201527f4e6174697665546f6b656e52656d6f74653a207a65726f20696e697469616c206044820152707265736572766520696d62616c616e636560781b60648201526084015b60405180910390fd5b6101e1838061024c565b6101ed84836012610262565b6101f681610299565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff1661024a57604051631afcd79f60e31b815260040160405180910390fd5b565b6102546101fc565b61025e8282610323565b5050565b61026a6101fc565b825160208401516040850151610281929190610386565b6102896103a1565b6102948383836103b1565b505050565b6102a16101fc565b606481106102ff5760405162461bcd60e51b815260206004820152602560248201527f4e6174697665546f6b656e52656d6f74653a20696e76616c69642070657263656044820152646e7461676560d81b60648201526084016101ce565b7f69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf50055565b61032b6101fc565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace036103778482610df9565b50600481016101f68382610df9565b61038e6101fc565b61039883826106fb565b6102948261071d565b6103a96101fc565b61024a61072e565b6103b96101fc565b5f7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0090507302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561042d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104519190610eb8565b815560608401516104b75760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d6520626c6f60448201526918dad8da185a5b88125160b21b60648201526084016101ce565b80546060850151036105315760405162461bcd60e51b815260206004820152603b60248201527f546f6b656e52656d6f74653a2063616e6e6f74206465706c6f7920746f20736160448201527f6d6520626c6f636b636861696e20617320746f6b656e20686f6d65000000000060648201526084016101ce565b60808401516001600160a01b03166105975760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d65206164646044820152637265737360e01b60648201526084016101ce565b60128460a0015160ff1611156106015760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20746f6b656e20686f6d6520646563696d616c73604482015268040e8dede40d0d2ced60bb1b60648201526084016101ce565b60128260ff1611156106615760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a20746f6b656e20646563696d616c7320746f6f206044820152630d0d2ced60e31b60648201526084016101ce565b60608401516001820155608084015160028201805460058401869055600684018054871560ff1990911617905560a08701516001600160a01b039093166001600160a81b031990911617600160a01b60ff808516919091029190911760ff60a81b1916600160a81b918616919091021790556106dd9083610758565b60048301805460ff1916911515919091179055600390910155505050565b6107036101fc565b61070b6107a0565b6107136107b0565b61025e82826107b8565b6107256101fc565b6100438161093c565b5f7fd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c75005b6001905550565b5f8060ff80851690841611818161077b576107738587610ee3565b60ff16610789565b6107858686610ee3565b60ff165b61079490600a610fe2565b96919550909350505050565b6107a86101fc565b61024a610976565b61024a6101fc565b6107c06101fc565b6001600160a01b03821661083c5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084016101ce565b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108c59190610eb8565b1161091a5760405162461bcd60e51b815260206004820152603260248201525f80516020615fce833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016101ce565b81546001600160a01b0319166001600160a01b0382161782556101f6836109a5565b6109446101fc565b6001600160a01b03811661096d57604051631e4fbdf760e01b81525f60048201526024016101ce565b61004381610b3d565b61097e6101fc565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00610751565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610a0c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a309190610eb8565b600283015490915081841115610a8f5760405162461bcd60e51b815260206004820152603160248201525f80516020615fce83398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016101ce565b808411610b045760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016101ce565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b0381118282101715610be357610be3610bad565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610c1157610c11610bad565b604052919050565b80516001600160a01b0381168114610c2f575f80fd5b919050565b5f82601f830112610c43575f80fd5b81516001600160401b03811115610c5c57610c5c610bad565b6020610c70601f8301601f19168201610be9565b8281528582848701011115610c83575f80fd5b5f5b83811015610ca0578581018301518282018401528201610c85565b505f928101909101919091529392505050565b5f805f80848603610120811215610cc8575f80fd5b60c0811215610cd5575f80fd5b50610cde610bc1565b610ce786610c19565b8152610cf560208701610c19565b60208201526040860151604082015260608601516060820152610d1a60808701610c19565b608082015260a086015160ff81168114610d32575f80fd5b60a082015260c08601519094506001600160401b03811115610d52575f80fd5b610d5e87828801610c34565b60e08701516101009097015195989097509350505050565b600181811c90821680610d8a57607f821691505b602082108103610da857634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561029457805f5260205f20601f840160051c81016020851015610dd35750805b601f840160051c820191505b81811015610df2575f8155600101610ddf565b5050505050565b81516001600160401b03811115610e1257610e12610bad565b610e2681610e208454610d76565b84610dae565b602080601f831160018114610e59575f8415610e425750858301515b5f19600386901b1c1916600185901b178555610eb0565b5f85815260208120601f198616915b82811015610e8757888601518255948401946001909101908401610e68565b5085821015610ea457878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f60208284031215610ec8575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b60ff8281168282160390811115610efc57610efc610ecf565b92915050565b600181815b80851115610f3c57815f1904821115610f2257610f22610ecf565b80851615610f2f57918102915b93841c9390800290610f07565b509250929050565b5f82610f5257506001610efc565b81610f5e57505f610efc565b8160018114610f745760028114610f7e57610f9a565b6001915050610efc565b60ff841115610f8f57610f8f610ecf565b50506001821b610efc565b5060208310610133831016604e8410600b8410161715610fbd575081810a610efc565b610fc78383610f02565b805f1904821115610fda57610fda610ecf565b029392505050565b5f610fed8383610f44565b9392505050565b614fcd806110015f395ff3fe608060405260043610610280575f3560e01c8063715018a61161014e578063b8a46d02116100c0578063dd62ed3e11610079578063dd62ed3e14610736578063e0fd9cb814610755578063ed0ae4b014610452578063ef793e2a14610769578063f2fde38b1461077d578063f3f981d81461079c5761028f565b8063b8a46d02146106b9578063c3cd6927146106d8578063c452165e146106ec578063c868efaa14610703578063d0e30db01461028f578063d2cc7a70146107225761028f565b80638f6cec88116101125780638f6cec8814610608578063909a6ac01461062757806395d89b4114610647578063973142971461065b578063a5717bc01461067a578063a9059cbb1461069a5761028f565b8063715018a61461057b57806371717c181461058f5780637ee3779a146105a55780638bf2fa94146105b95780638da5cb5b146105cc5761028f565b80632e1a7d4d116101f25780634511243e116101ab5780634511243e146104b55780635507f3d1146104d457806355538c8b146104ea5780635eb99514146105095780636e6eef8d1461052857806370a082311461053b5761028f565b80632e1a7d4d146103e6578063313ce56714610405578063329c3e1214610420578063347212c41461045257806335cac1591461046e5780634213cf78146104a15761028f565b806315beb59f1161024457806315beb59f1461035557806318160ddd1461036a5780631906529c1461037e57806323b872dd14610392578063254ac160146103b15780632b0d8f18146103c75761028f565b806302a30c7d1461029757806306fdde03146102c05780630733c8c8146102e1578063095ea7b3146103035780630ca1c5c9146103225761028f565b3661028f5761028d6107bb565b005b61028d6107bb565b3480156102a2575f80fd5b506102ab6107fc565b60405190151581526020015b60405180910390f35b3480156102cb575f80fd5b506102d4610813565b6040516102b79190613f06565b3480156102ec575f80fd5b506102f56108d3565b6040519081526020016102b7565b34801561030e575f80fd5b506102ab61031d366004613f3c565b6108e7565b34801561032d575f80fd5b507f69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf501546102f5565b348015610360575f80fd5b506102f56105dc81565b348015610375575f80fd5b506102f5610900565b348015610389575f80fd5b506102f561091b565b34801561039d575f80fd5b506102ab6103ac366004613f66565b610972565b3480156103bc575f80fd5b506102f56201fbd081565b3480156103d2575f80fd5b5061028d6103e1366004613fa4565b610997565b3480156103f1575f80fd5b5061028d610400366004613fbf565b610a99565b348015610410575f80fd5b50604051601281526020016102b7565b34801561042b575f80fd5b5061043a6001600160991b0181565b6040516001600160a01b0390911681526020016102b7565b34801561045d575f80fd5b5061043a62010203600160981b0181565b348015610479575f80fd5b506102f57f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0081565b3480156104ac575f80fd5b506102f5610ae5565b3480156104c0575f80fd5b5061028d6104cf366004613fa4565b610af6565b3480156104df575f80fd5b506102f56205302081565b3480156104f5575f80fd5b5061028d610504366004613fbf565b610be5565b348015610514575f80fd5b5061028d610523366004613fbf565b610ef7565b61028d610536366004613fd6565b610f08565b348015610546575f80fd5b506102f5610555366004613fa4565b6001600160a01b03165f9081525f80516020614f18833981519152602052604090205490565b348015610586575f80fd5b5061028d610f36565b34801561059a575f80fd5b506102f56205573081565b3480156105b0575f80fd5b506102ab610f47565b61028d6105c736600461400d565b610f5e565b3480156105d7575f80fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031661043a565b348015610613575f80fd5b5061028d61062236600461414d565b610f8c565b348015610632575f80fd5b506102f55f80516020614f7883398151915281565b348015610652575f80fd5b506102d461109e565b348015610666575f80fd5b506102ab610675366004613fa4565b6110dc565b348015610685575f80fd5b506102f55f80516020614f5883398151915281565b3480156106a5575f80fd5b506102ab6106b4366004613f3c565b6110f5565b3480156106c4575f80fd5b5061028d6106d3366004614217565b611102565b3480156106e3575f80fd5b5061043a611276565b3480156106f7575f80fd5b5061043a600160981b81565b34801561070e575f80fd5b5061028d61071d366004614227565b611293565b34801561072d575f80fd5b506102f5611450565b348015610741575f80fd5b506102f56107503660046142a8565b611465565b348015610760575f80fd5b506102f56114ae565b348015610774575f80fd5b506102f56114c2565b348015610788575f80fd5b5061028d610797366004613fa4565b6114d6565b3480156107a7575f80fd5b506102f56107b6366004613fbf565b611510565b60405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a26107fa3334611526565b565b5f8061080661155e565b6006015460ff1692915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0380546060915f80516020614f1883398151915291610851906142df565b80601f016020809104026020016040519081016040528092919081815260200182805461087d906142df565b80156108c85780601f1061089f576101008083540402835291602001916108c8565b820191905f5260205f20905b8154815290600101906020018083116108ab57829003601f168201915b505050505091505090565b5f806108dd61155e565b6003015492915050565b5f336108f4818585611582565b60019150505b92915050565b5f805f80516020614f188339815191525b6002015492915050565b5f5f80516020614f588339815191528161094462010203600160981b0131600160981b31614325565b90505f61094f6114c2565b836001015461095e9190614325565b905061096a8282614338565b935050505090565b5f3361097f858285611594565b61098a8585856115f1565b60019150505b9392505050565b5f80516020614f788339815191526109ad61164e565b6001600160a01b0382166109dc5760405162461bcd60e51b81526004016109d39061434b565b60405180910390fd5b6109e68183611656565b15610a495760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b60648201526084016109d3565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b60405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a2610ad83382611677565b610ae233826116ab565b50565b5f80610aef61155e565b5492915050565b5f80516020614f78833981519152610b0c61164e565b6001600160a01b038216610b325760405162461bcd60e51b81526004016109d39061434b565b610b3c8183611656565b610b9a5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b60648201526084016109d3565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b5f80516020614f388339815191528054600114610c145760405162461bcd60e51b81526004016109d390614399565b600281557f69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf502545f80516020614f5883398151915290600160981b31908111610cd25760405162461bcd60e51b8152602060048201526044602482018190527f4e6174697665546f6b656e52656d6f74653a206275726e206164647265737320908201527f62616c616e6365206e6f742067726561746572207468616e206c6173742072656064820152631c1bdc9d60e21b608482015260a4016109d3565b5f826002015482610ce39190614338565b90505f6064845f015483610cf791906143dd565b610d0191906143f4565b90505f610d0e8284614338565b6002860185905590508115610d3157610d27308361173e565b610d313083611526565b5f610d4b610d3d6108d3565b610d45610f47565b846117eb565b11610db55760405162461bcd60e51b815260206004820152603460248201527f4e6174697665546f6b656e52656d6f74653a207a65726f207363616c6564206160448201527336b7bab73a103a37903932b837b93a10313ab93760611b60648201526084016109d3565b604080518082018252600181528151808301835262010203600160981b018152602080820185905292515f9380840192610df192909101614427565b60405160208183030381529060405281525090505f610eac6040518060c00160405280610e1c6114ae565b8152602001610e29611276565b6001600160a01b0316815260408051808201825230815260208181018a905283015281018c90526060015f5b604051908082528060200260200182016040528015610e7e578160200160208202803683370190505b50815260200184604051602001610e959190614447565b604051602081830303815290604052815250611800565b9050807f0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a584604051610ee091815260200190565b60405180910390a250506001909555505050505050565b610eff61164e565b610ae28161191b565b610f106107fc565b610f2c5760405162461bcd60e51b81526004016109d390614489565b610ae28134611ab3565b610f3e611b2a565b6107fa5f611b85565b5f80610f5161155e565b6004015460ff1692915050565b610f666107fc565b610f825760405162461bcd60e51b81526004016109d390614489565b610ae28134611bf5565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610fd05750825b90505f826001600160401b03166001148015610feb5750303b155b905081158015610ff9575080155b156110175760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561104157845460ff60401b1916600160401b1785555b61104d89898989611c61565b831561109357845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f80516020614f1883398151915291610851906142df565b5f5f80516020614f788339815191526109908184611656565b5f336108f48185856115f1565b5f61110b61155e565b6006810154909150610100900460ff16156111685760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e52656d6f74653a20616c726561647920726567697374657265640060448201526064016109d3565b604080516060808201835260058401548252600284015460ff600160a01b820481166020808601918252600160a81b9093048216858701908152865180880188525f808252885188518188015293518516848a015291519093168286015286518083039095018552608090910190955280820192909252919290916111fd906111f390870187613fa4565b8660200135611cf1565b6040805160c0810182526001870154815260028701546001600160a01b03166020808301919091528251808401845293945061126e939192830191908190611247908b018b613fa4565b6001600160a01b0316815260209081018690529082526201fbd0908201526040015f610e55565b505050505050565b5f8061128061155e565b600201546001600160a01b031692915050565b61129b611d38565b5f5f80516020614f7883398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611306573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132a91906144d8565b10156113915760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b60648201526084016109d3565b61139b8133611656565b156114015760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b60648201526084016109d3565b611441858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611d8292505050565b5061144a611f99565b50505050565b5f805f80516020614f78833981519152610911565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b5f806114b861155e565b6001015492915050565b5f806114cc61155e565b6005015492915050565b6114de611b2a565b6001600160a01b03811661150757604051631e4fbdf760e01b81525f60048201526024016109d3565b610ae281611b85565b5f600561151e83601f614325565b901c92915050565b6001600160a01b03821661154f5760405163ec442f0560e01b81525f60048201526024016109d3565b61155a5f8383611fc3565b5050565b7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0090565b61158f83838360016120fc565b505050565b5f61159f8484611465565b90505f19811461144a57818110156115e357604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016109d3565b61144a84848484035f6120fc565b6001600160a01b03831661161a57604051634b637e8f60e11b81525f60048201526024016109d3565b6001600160a01b0382166116435760405163ec442f0560e01b81525f60048201526024016109d3565b61158f838383611fc3565b6107fa611b2a565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b6001600160a01b0382166116a057604051634b637e8f60e11b81525f60048201526024016109d3565b61155a825f83611fc3565b804710156116ce5760405163cd78605960e01b81523060048201526024016109d3565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611717576040519150601f19603f3d011682016040523d82523d5f602084013e61171c565b606091505b505090508061158f57604051630a12f52160e11b815260040160405180910390fd5b7f69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf50180545f80516020614f588339815191529183915f9061177f908490614325565b90915550506040516327ad555d60e11b81526001600160a01b0384166004820152602481018390526001600160991b0190634f5aaaba906044015f604051808303815f87803b1580156117d0575f80fd5b505af11580156117e2573d5f803e3d5ffd5b50505050505050565b5f6117f88484845f6121df565b949350505050565b5f8061180a61220f565b604084015160200151909150156118af576040830151516001600160a01b031661188c5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b60648201526084016109d3565b6040830151602081015190516118af916001600160a01b039091169083906122ff565b604051630624488560e41b81526001600160a01b038216906362448850906118db9086906004016144ef565b6020604051808303815f875af11580156118f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061099091906144d8565b5f80516020614f7883398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa15801561196f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199391906144d8565b600283015490915081841115611a055760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016109d3565b808411611a7a5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016109d3565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b5f80516020614f388339815191528054600114611ae25760405162461bcd60e51b81526004016109d390614399565b600281555f611aef61155e565b9050611afa84612386565b6001810154843503611b1657611b1084846125c0565b50611b22565b611b1084846127e4565b505b600190555050565b33611b5c7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146107fa5760405163118cdaa760e01b81523360048201526024016109d3565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f80516020614f388339815191528054600114611c245760405162461bcd60e51b81526004016109d390614399565b600281555f611c3161155e565b9050611c3c84612a85565b6001810154843503611c5757611c528484612b70565b611b20565b611b208484612cdf565b611c69612ea5565b815f03611cd25760405162461bcd60e51b815260206004820152603160248201527f4e6174697665546f6b656e52656d6f74653a207a65726f20696e697469616c206044820152707265736572766520696d62616c616e636560781b60648201526084016109d3565b611cdc8384612eee565b611ce884836012612f00565b61144a81612f31565b5f815f03611d0057505f6108fa565b306001600160a01b03841603611d2d57611d1b333084611594565b611d263330846115f1565b50806108fa565b610990833384612fa8565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00805460011901611d7c57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f611d8b61155e565b905080600101548414611df25760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20696e76616c696420736f7572636520626c6f636044820152681ad8da185a5b88125160ba1b60648201526084016109d3565b60028101546001600160a01b03848116911614611e645760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a20696e76616c6964206f726967696e2073656e646044820152696572206164647265737360b01b60648201526084016109d3565b5f82806020019051810190611e7991906145e8565b6006830154909150610100900460ff161580611e9a5750600682015460ff16155b15611eb15760068201805461ffff19166101011790555b600181516004811115611ec657611ec6614413565b03611efd575f8160200151806020019051810190611ee49190614670565b9050611ef7815f0151826020015161310b565b50611f92565b600281516004811115611f1257611f12614413565b03611f40575f8160200151806020019051810190611f3091906146a8565b9050611ef7818260800151613158565b60405162461bcd60e51b815260206004820152602160248201527f546f6b656e52656d6f74653a20696e76616c6964206d657373616765207479706044820152606560f81b60648201526084016109d3565b5050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b5f80516020614f188339815191526001600160a01b038416611ffd5781816002015f828254611ff29190614325565b9091555061206d9050565b6001600160a01b0384165f908152602082905260409020548281101561204f5760405163391434e360e21b81526001600160a01b038616600482015260248101829052604481018490526064016109d3565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b03831661208b5760028101805483900390556120a9565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516120ee91815260200190565b60405180910390a350505050565b5f80516020614f188339815191526001600160a01b0385166121335760405163e602df0560e01b81525f60048201526024016109d3565b6001600160a01b03841661215c57604051634a1406b160e11b81525f60048201526024016109d3565b6001600160a01b038086165f90815260018301602090815260408083209388168352929052208390558115611f9257836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925856040516121d091815260200190565b60405180910390a35050505050565b5f811515841515036121fc576121f585846143dd565b90506117f8565b61220685846143f4565b95945050505050565b5f80516020614f7883398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612269573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061228d9190614772565b90506122998282611656565b156108fa5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b60648201526084016109d3565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa15801561234c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061237091906144d8565b905061144a84846123818585614325565b613282565b80356123a45760405162461bcd60e51b81526004016109d39061478d565b5f6123b56040830160208401613fa4565b6001600160a01b0316036123db5760405162461bcd60e51b81526004016109d3906147d8565b5f6123ec6060830160408401613fa4565b6001600160a01b0316036124575760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420636f6e7460448201526b72616374206164647265737360a01b60648201526084016109d3565b5f81608001351161247a5760405162461bcd60e51b81526004016109d390614835565b5f8160a00135116124db5760405162461bcd60e51b815260206004820152602560248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420676173206044820152641b1a5b5a5d60da1b60648201526084016109d3565b80608001358160a00135106125435760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a20696e76616c696420726563697069656e742067604482015267185cc81b1a5b5a5d60c21b60648201526084016109d3565b5f612555610100830160e08401613fa4565b6001600160a01b031603610ae25760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f2066616c6c6261636b20726563697060448201526b69656e74206164647265737360a01b60648201526084016109d3565b5f6125c961155e565b90506125f96125de6040850160208601613fa4565b6101408501356125f460e0870160c08801613fa4565b61333f565b5f6126218361261061012087016101008801613fa4565b86610120013587610140013561343c565b6040805180820190915291945091505f908060028152602001604051806101000160405280865f01548152602001306001600160a01b031681526020016126653390565b6001600160a01b0316815260200161268360608a0160408b01613fa4565b6001600160a01b03168152602081018890526040016126a560608a018a614879565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a089013560208201526040016126f96101008a0160e08b01613fa4565b6001600160a01b0316905260405161271491906020016148bb565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92612796928201908061276e6101208c016101008d01613fa4565b6001600160a01b03168152602090810188905290825260808a0135908201526040015f610e55565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b1688886040516127d49291906149c2565b60405180910390a3505050505050565b5f6127ed61155e565b905061281983356128046040860160208701613fa4565b61281460e0870160c08801613fa4565b6134ff565b5f6128308361261061012087016101008801613fa4565b6040805180820190915291945091505f90806004815260200160405180610160016040528061285c3390565b6001600160a01b03168152602001885f013581526020018860200160208101906128869190613fa4565b6001600160a01b031681526020016128a460608a0160408b01613fa4565b6001600160a01b03168152602081018890526040016128c660608a018a614879565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a0890135602082015260400161291a6101008a0160e08b01613fa4565b6001600160a01b031681526080890135602082015260400161294260e08a0160c08b01613fa4565b6001600160a01b03168152610140890135602091820152604051612967929101614ad0565b60408051601f19818403018152919052905290505f6105dc61299661298f6060890189614879565b9050611510565b6129a091906143dd565b6129ad9062055730614325565b6040805160c0810182526001870154815260028701546001600160a01b03166020820152815180830183529293505f92612a3692820190806129f76101208d016101008e01613fa4565b6001600160a01b031681526020908101899052908252818101869052604080515f815280830182528184015251606090920191610e9591889101614447565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168989604051612a749291906149c2565b60405180910390a350505050505050565b5f612a966060830160408401613fa4565b6001600160a01b031603612af85760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e74206164647260448201526265737360e81b60648201526084016109d3565b5f8160c0013511612b1b5760405162461bcd60e51b81526004016109d390614835565b8035612b395760405162461bcd60e51b81526004016109d39061478d565b5f612b4a6040830160208401613fa4565b6001600160a01b031603610ae25760405162461bcd60e51b81526004016109d3906147d8565b5f612b7961155e565b9050612ba4612b8e6040850160208601613fa4565b60a08501356125f4610100870160e08801613fa4565b5f612bc883612bb96080870160608801613fa4565b86608001358760a0013561343c565b6040805180820190915291945091505f9080600181526020016040518060400160405280886040016020810190612bff9190613fa4565b6001600160a01b0316815260200187815250604051602001612c219190614427565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92612ca19282019080612c7960808c0160608d01613fa4565b6001600160a01b03168152602090810188905290825260c08a0135908201526040015f610e55565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb5288886040516127d4929190614bad565b5f612ce861155e565b9050612d108335612cff6040860160208701613fa4565b612814610100870160e08801613fa4565b5f612d2583612bb96080870160608801613fa4565b60408051808201825260038152815160e081018352883581529396509193505f9260208084019282820191612d5e918b01908b01613fa4565b6001600160a01b03168152602001612d7c60608a0160408b01613fa4565b6001600160a01b031681526020810188905260a0890135604082015260c08901356060820152608001612db66101008a0160e08b01613fa4565b6001600160a01b03169052604051612e269190602001815181526020808301516001600160a01b0390811691830191909152604080840151821690830152606080840151908301526080808401519083015260a0808401519083015260c092830151169181019190915260e00190565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92612ca19282019080612e7e60808c0160608d01613fa4565b6001600160a01b03168152602090810188905290825262053020908201526040015f610e55565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166107fa57604051631afcd79f60e31b815260040160405180910390fd5b612ef6612ea5565b61155a828261359d565b612f08612ea5565b612f1e835f0151846020015185604001516135ed565b612f26613608565b61158f838383613618565b612f39612ea5565b60648110612f975760405162461bcd60e51b815260206004820152602560248201527f4e6174697665546f6b656e52656d6f74653a20696e76616c69642070657263656044820152646e7461676560d81b60648201526084016109d3565b5f80516020614f5883398151915255565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa158015612fee573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061301291906144d8565b90506130296001600160a01b03861685308661393c565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa15801561306d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061309191906144d8565b90508181116130f75760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016109d3565b6131018282614338565b9695505050505050565b816001600160a01b03167f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b8260405161314691815260200190565b60405180910390a261155a828261173e565b613162308261173e565b5f825f0151836020015184604001518560a001516040516024016131899493929190614c4c565b60408051601f198184030181529190526020810180516001600160e01b031663161b12ff60e11b17905260c084015160608501519192505f916131cf9190859085613975565b905080156132235783606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff48460405161321691815260200190565b60405180910390a261144a565b83606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb08460405161326291815260200190565b60405180910390a260e084015161144a906001600160a01b0316846116ab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526132d38482613a45565b61144a576040516001600160a01b0384811660248301525f604483015261333591869182169063095ea7b3906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613ae2565b61144a8482613ae2565b5f61334861155e565b60028101549091506001600160a01b0385811691161461337a5760405162461bcd60e51b81526004016109d390614c7d565b82156133d45760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f207365636f6e646172792060448201526266656560e81b60648201526084016109d3565b6001600160a01b0382161561144a5760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f206d756c74692d686f702060448201526766616c6c6261636b60c01b60648201526084016109d3565b5f805f61344761155e565b905061345287613b43565b965061345e8686611cf1565b600382015460048301549196506134789160ff16866117eb565b60038201546004830154613490919060ff168a6117eb565b116134f25760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a20696e73756666696369656e7420746f6b656e7360448201526b103a37903a3930b739b332b960a11b60648201526084016109d3565b5094959294509192505050565b5f61350861155e565b8054909150840361353b57306001600160a01b0384160361353b5760405162461bcd60e51b81526004016109d390614c7d565b6001600160a01b03821661144a5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f206d756c74692d686f702066616c6c6044820152636261636b60e01b60648201526084016109d3565b6135a5612ea5565b5f80516020614f188339815191527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace036135de8482614d1e565b506004810161144a8382614d1e565b6135f5612ea5565b6135ff8382613b5b565b61158f82613b7d565b613610612ea5565b6107fa613b8e565b613620612ea5565b5f61362961155e565b90506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561366e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061369291906144d8565b815560608401516136f85760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d6520626c6f60448201526918dad8da185a5b88125160b21b60648201526084016109d3565b80546060850151036137725760405162461bcd60e51b815260206004820152603b60248201527f546f6b656e52656d6f74653a2063616e6e6f74206465706c6f7920746f20736160448201527f6d6520626c6f636b636861696e20617320746f6b656e20686f6d65000000000060648201526084016109d3565b60808401516001600160a01b03166137d85760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d65206164646044820152637265737360e01b60648201526084016109d3565b60128460a0015160ff1611156138425760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20746f6b656e20686f6d6520646563696d616c73604482015268040e8dede40d0d2ced60bb1b60648201526084016109d3565b60128260ff1611156138a25760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a20746f6b656e20646563696d616c7320746f6f206044820152630d0d2ced60e31b60648201526084016109d3565b60608401516001820155608084015160028201805460058401869055600684018054871560ff1990911617905560a08701516001600160a01b039093166001600160a81b031990911617600160a01b60ff808516919091029190911760ff60a81b1916600160a81b9186169190910217905561391e9083613ba2565b60048301805460ff1916911515919091179055600390910155505050565b6040516001600160a01b03848116602483015283811660448301526064820183905261144a9186918216906323b872dd90608401613303565b5f845a10156139c65760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e7420676173000000000060448201526064016109d3565b83471015613a165760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c756500000060448201526064016109d3565b826001600160a01b03163b5f03613a2e57505f6117f8565b5f805f84516020860188888bf19695505050505050565b5f805f846001600160a01b031684604051613a609190614dd9565b5f604051808303815f865af19150503d805f8114613a99576040519150601f19603f3d011682016040523d82523d5f602084013e613a9e565b606091505b5091509150818015613ac8575080511580613ac8575080806020019051810190613ac89190614df4565b80156122065750505050506001600160a01b03163b151590565b5f613af66001600160a01b03841683613bec565b905080515f14158015613b1a575080806020019051810190613b189190614df4565b155b1561158f57604051635274afe760e01b81526001600160a01b03841660048201526024016109d3565b5f613b5762010203600160981b01836116ab565b5090565b613b63612ea5565b613b6b613bf9565b613b73613c09565b61155a8282613c11565b613b85612ea5565b610ae281613d95565b5f5f80516020614f38833981519152611fbc565b5f8060ff808516908416118181613bc557613bbd8587614e13565b60ff16613bd3565b613bcf8686614e13565b60ff165b613bde90600a614f0c565b9350909150505b9250929050565b606061099083835f613d9d565b613c01612ea5565b6107fa613e2c565b6107fa612ea5565b613c19612ea5565b6001600160a01b038216613c955760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084016109d3565b5f5f80516020614f7883398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ce7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d0b91906144d8565b11613d735760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b60648201526084016109d3565b81546001600160a01b0319166001600160a01b03821617825561144a8361191b565b6114de612ea5565b606081471015613dc25760405163cd78605960e01b81523060048201526024016109d3565b5f80856001600160a01b03168486604051613ddd9190614dd9565b5f6040518083038185875af1925050503d805f8114613e17576040519150601f19603f3d011682016040523d82523d5f602084013e613e1c565b606091505b5091509150613101868383613e34565b611f99612ea5565b606082613e4957613e4482613e90565b610990565b8151158015613e6057506001600160a01b0384163b155b15613e8957604051639996b31560e01b81526001600160a01b03851660048201526024016109d3565b5080610990565b805115613ea05780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f5b83811015613ed3578181015183820152602001613ebb565b50505f910152565b5f8151808452613ef2816020860160208601613eb9565b601f01601f19169290920160200192915050565b602081525f6109906020830184613edb565b6001600160a01b0381168114610ae2575f80fd5b8035613f3781613f18565b919050565b5f8060408385031215613f4d575f80fd5b8235613f5881613f18565b946020939093013593505050565b5f805f60608486031215613f78575f80fd5b8335613f8381613f18565b92506020840135613f9381613f18565b929592945050506040919091013590565b5f60208284031215613fb4575f80fd5b813561099081613f18565b5f60208284031215613fcf575f80fd5b5035919050565b5f60208284031215613fe6575f80fd5b81356001600160401b03811115613ffb575f80fd5b82016101608185031215610990575f80fd5b5f610100828403121561401e575f80fd5b50919050565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b038111828210171561405a5761405a614024565b60405290565b604080519081016001600160401b038111828210171561405a5761405a614024565b60405161010081016001600160401b038111828210171561405a5761405a614024565b604051601f8201601f191681016001600160401b03811182821017156140cd576140cd614024565b604052919050565b5f6001600160401b038211156140ed576140ed614024565b50601f01601f191660200190565b5f82601f83011261410a575f80fd5b813561411d614118826140d5565b6140a5565b818152846020838601011115614131575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80848603610120811215614162575f80fd5b60c081121561416f575f80fd5b50614178614038565b853561418381613f18565b8152602086013561419381613f18565b80602083015250604086013560408201526060860135606082015260808601356141bc81613f18565b608082015260a086013560ff811681146141d4575f80fd5b60a0820152935060c08501356001600160401b038111156141f3575f80fd5b6141ff878288016140fb565b949794965050505060e0830135926101000135919050565b5f6040828403121561401e575f80fd5b5f805f806060858703121561423a575f80fd5b84359350602085013561424c81613f18565b925060408501356001600160401b0380821115614267575f80fd5b818701915087601f83011261427a575f80fd5b813581811115614288575f80fd5b886020828501011115614299575f80fd5b95989497505060200194505050565b5f80604083850312156142b9575f80fd5b82356142c481613f18565b915060208301356142d481613f18565b809150509250929050565b600181811c908216806142f357607f821691505b60208210810361401e57634e487b7160e01b5f52602260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156108fa576108fa614311565b818103818111156108fa576108fa614311565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b80820281158282048414176108fa576108fa614311565b5f8261440e57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffd5b81516001600160a01b0316815260208083015190820152604081016108fa565b602081525f82516005811061446a57634e487b7160e01b5f52602160045260245ffd5b8060208401525060208301516040808401526117f86060840182613edb565b6020808252602f908201527f4e6174697665546f6b656e52656d6f74653a20636f6e747261637420756e646560408201526e1c98dbdb1b185d195c985b1a5e9959608a1b606082015260800190565b5f602082840312156144e8575f80fd5b5051919050565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b8084101561457c5784518316825293850193600193909301929085019061455a565b5060a0880151878203601f190160e0890152945061459a8186613edb565b98975050505050505050565b5f82601f8301126145b5575f80fd5b81516145c3614118826140d5565b8181528460208386010111156145d7575f80fd5b6117f8826020830160208701613eb9565b5f602082840312156145f8575f80fd5b81516001600160401b038082111561460e575f80fd5b9083019060408286031215614621575f80fd5b614629614060565b825160058110614637575f80fd5b815260208301518281111561464a575f80fd5b614656878286016145a6565b60208301525095945050505050565b8051613f3781613f18565b5f60408284031215614680575f80fd5b614688614060565b825161469381613f18565b81526020928301519281019290925250919050565b5f602082840312156146b8575f80fd5b81516001600160401b03808211156146ce575f80fd5b9083019061010082860312156146e2575f80fd5b6146ea614082565b825181526146fa60208401614665565b602082015261470b60408401614665565b604082015261471c60608401614665565b60608201526080830151608082015260a08301518281111561473c575f80fd5b614748878286016145a6565b60a08301525060c083015160c082015261476460e08401614665565b60e082015295945050505050565b5f60208284031215614782575f80fd5b815161099081613f18565b6020808252602b908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20626c60408201526a1bd8dad8da185a5b88125160aa1b606082015260800190565b60208082526037908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20746f60408201527f6b656e207472616e736665727265722061646472657373000000000000000000606082015260800190565b60208082526024908201527f546f6b656e52656d6f74653a207a65726f20726571756972656420676173206c6040820152631a5b5a5d60e21b606082015260800190565b5f808335601e1984360301811261488e575f80fd5b8301803591506001600160401b038211156148a7575f80fd5b602001915036819003821315613be5575f80fd5b60208152815160208201525f602083015160018060a01b0380821660408501528060408601511660608501525050606083015161490360808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c085015261492a610120850183613edb565b915060c085015160e085015260e085015161494f828601826001600160a01b03169052565b5090949350505050565b5f808335601e1984360301811261496e575f80fd5b83016020810192503590506001600160401b0381111561498c575f80fd5b803603821315613be5575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60408152823560408201525f6149da60208501613f2c565b6001600160a01b031660608301526149f460408501613f2c565b6001600160a01b03166080830152614a0f6060850185614959565b6101608060a0860152614a276101a08601838561499a565b9250608087013560c086015260a087013560e0860152614a4960c08801613f2c565b9150610100614a62818701846001600160a01b03169052565b614a6e60e08901613f2c565b9250610120614a87818801856001600160a01b03169052565b614a92828a01613f2c565b93506101409150614aad828801856001600160a01b03169052565b880135918601919091529095013561018084015260209092019290925292915050565b60208152614aea6020820183516001600160a01b03169052565b602082015160408201525f6040830151614b0f60608401826001600160a01b03169052565b5060608301516001600160a01b038116608084015250608083015160a083015260a08301516101608060c0850152614b4b610180850183613edb565b915060c085015160e085015260e0850151610100614b73818701836001600160a01b03169052565b860151610120868101919091528601519050610140614b9c818701836001600160a01b03169052565b959095015193019290925250919050565b8235815261012081016020840135614bc481613f18565b6001600160a01b039081166020840152604085013590614be382613f18565b166040830152614bf560608501613f2c565b6001600160a01b0381166060840152506080840135608083015260a084013560a083015260c084013560c0830152614c2f60e08501613f2c565b6001600160a01b031660e083015261010090910191909152919050565b8481526001600160a01b038481166020830152831660408201526080606082018190525f9061310190830184613edb565b6020808252603a908201527f546f6b656e52656d6f74653a20696e76616c69642064657374696e6174696f6e60408201527f20746f6b656e207472616e736665727265722061646472657373000000000000606082015260800190565b601f82111561158f57805f5260205f20601f840160051c81016020851015614cff5750805b601f840160051c820191505b81811015611f92575f8155600101614d0b565b81516001600160401b03811115614d3757614d37614024565b614d4b81614d4584546142df565b84614cda565b602080601f831160018114614d7e575f8415614d675750858301515b5f19600386901b1c1916600185901b17855561126e565b5f85815260208120601f198616915b82811015614dac57888601518255948401946001909101908401614d8d565b5085821015614dc957878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f8251614dea818460208701613eb9565b9190910192915050565b5f60208284031215614e04575f80fd5b81518015158114610990575f80fd5b60ff82811682821603908111156108fa576108fa614311565b600181815b80851115614e6657815f1904821115614e4c57614e4c614311565b80851615614e5957918102915b93841c9390800290614e31565b509250929050565b5f82614e7c575060016108fa565b81614e8857505f6108fa565b8160018114614e9e5760028114614ea857614ec4565b60019150506108fa565b60ff841115614eb957614eb9614311565b50506001821b6108fa565b5060208310610133831016604e8410600b8410161715614ee7575081810a6108fa565b614ef18383614e2c565b805f1904821115614f0457614f04614311565b029392505050565b5f6109908383614e6e56fe52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00d2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c750069a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf500de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a26469706673582212207455deeb3a449fbcecaf7e02b999366c0e213f93b1c19958c2f5ef6904d9c71c64736f6c6343000819003354656c65706f7274657252656769737472794170703a20696e76616c69642054", +} + +// NativeTokenRemoteABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenRemoteMetaData.ABI instead. +var NativeTokenRemoteABI = NativeTokenRemoteMetaData.ABI + +// NativeTokenRemoteBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenRemoteMetaData.Bin instead. +var NativeTokenRemoteBin = NativeTokenRemoteMetaData.Bin + +// DeployNativeTokenRemote deploys a new Ethereum contract, binding an instance of NativeTokenRemote to it. +func DeployNativeTokenRemote(auth *bind.TransactOpts, backend bind.ContractBackend, settings TokenRemoteSettings, nativeAssetSymbol string, initialReserveImbalance *big.Int, burnedFeesReportingRewardPercentage *big.Int) (common.Address, *types.Transaction, *NativeTokenRemote, error) { + parsed, err := NativeTokenRemoteMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NativeTokenRemoteBin), backend, settings, nativeAssetSymbol, initialReserveImbalance, burnedFeesReportingRewardPercentage) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenRemote{NativeTokenRemoteCaller: NativeTokenRemoteCaller{contract: contract}, NativeTokenRemoteTransactor: NativeTokenRemoteTransactor{contract: contract}, NativeTokenRemoteFilterer: NativeTokenRemoteFilterer{contract: contract}}, nil +} + +// NativeTokenRemote is an auto generated Go binding around an Ethereum contract. +type NativeTokenRemote struct { + NativeTokenRemoteCaller // Read-only binding to the contract + NativeTokenRemoteTransactor // Write-only binding to the contract + NativeTokenRemoteFilterer // Log filterer for contract events +} + +// NativeTokenRemoteCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenRemoteCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenRemoteTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenRemoteTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenRemoteFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenRemoteFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenRemoteSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenRemoteSession struct { + Contract *NativeTokenRemote // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenRemoteCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenRemoteCallerSession struct { + Contract *NativeTokenRemoteCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenRemoteTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenRemoteTransactorSession struct { + Contract *NativeTokenRemoteTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenRemoteRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenRemoteRaw struct { + Contract *NativeTokenRemote // Generic contract binding to access the raw methods on +} + +// NativeTokenRemoteCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenRemoteCallerRaw struct { + Contract *NativeTokenRemoteCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenRemoteTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenRemoteTransactorRaw struct { + Contract *NativeTokenRemoteTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenRemote creates a new instance of NativeTokenRemote, bound to a specific deployed contract. +func NewNativeTokenRemote(address common.Address, backend bind.ContractBackend) (*NativeTokenRemote, error) { + contract, err := bindNativeTokenRemote(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenRemote{NativeTokenRemoteCaller: NativeTokenRemoteCaller{contract: contract}, NativeTokenRemoteTransactor: NativeTokenRemoteTransactor{contract: contract}, NativeTokenRemoteFilterer: NativeTokenRemoteFilterer{contract: contract}}, nil +} + +// NewNativeTokenRemoteCaller creates a new read-only instance of NativeTokenRemote, bound to a specific deployed contract. +func NewNativeTokenRemoteCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenRemoteCaller, error) { + contract, err := bindNativeTokenRemote(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenRemoteCaller{contract: contract}, nil +} + +// NewNativeTokenRemoteTransactor creates a new write-only instance of NativeTokenRemote, bound to a specific deployed contract. +func NewNativeTokenRemoteTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenRemoteTransactor, error) { + contract, err := bindNativeTokenRemote(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenRemoteTransactor{contract: contract}, nil +} + +// NewNativeTokenRemoteFilterer creates a new log filterer instance of NativeTokenRemote, bound to a specific deployed contract. +func NewNativeTokenRemoteFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenRemoteFilterer, error) { + contract, err := bindNativeTokenRemote(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenRemoteFilterer{contract: contract}, nil +} + +// bindNativeTokenRemote binds a generic wrapper to an already deployed contract. +func bindNativeTokenRemote(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenRemoteMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenRemote *NativeTokenRemoteRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenRemote.Contract.NativeTokenRemoteCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenRemote *NativeTokenRemoteRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.NativeTokenRemoteTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenRemote *NativeTokenRemoteRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.NativeTokenRemoteTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenRemote *NativeTokenRemoteCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenRemote.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenRemote *NativeTokenRemoteTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenRemote *NativeTokenRemoteTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.contract.Transact(opts, method, params...) +} + +// BURNEDFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0x347212c4. +// +// Solidity: function BURNED_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCaller) BURNEDFORTRANSFERADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "BURNED_FOR_TRANSFER_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNEDFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0x347212c4. +// +// Solidity: function BURNED_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteSession) BURNEDFORTRANSFERADDRESS() (common.Address, error) { + return _NativeTokenRemote.Contract.BURNEDFORTRANSFERADDRESS(&_NativeTokenRemote.CallOpts) +} + +// BURNEDFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0x347212c4. +// +// Solidity: function BURNED_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) BURNEDFORTRANSFERADDRESS() (common.Address, error) { + return _NativeTokenRemote.Contract.BURNEDFORTRANSFERADDRESS(&_NativeTokenRemote.CallOpts) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCaller) BURNEDTXFEESADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "BURNED_TX_FEES_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenRemote.Contract.BURNEDTXFEESADDRESS(&_NativeTokenRemote.CallOpts) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenRemote.Contract.BURNEDTXFEESADDRESS(&_NativeTokenRemote.CallOpts) +} + +// HOMECHAINBURNADDRESS is a free data retrieval call binding the contract method 0xed0ae4b0. +// +// Solidity: function HOME_CHAIN_BURN_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCaller) HOMECHAINBURNADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "HOME_CHAIN_BURN_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// HOMECHAINBURNADDRESS is a free data retrieval call binding the contract method 0xed0ae4b0. +// +// Solidity: function HOME_CHAIN_BURN_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteSession) HOMECHAINBURNADDRESS() (common.Address, error) { + return _NativeTokenRemote.Contract.HOMECHAINBURNADDRESS(&_NativeTokenRemote.CallOpts) +} + +// HOMECHAINBURNADDRESS is a free data retrieval call binding the contract method 0xed0ae4b0. +// +// Solidity: function HOME_CHAIN_BURN_ADDRESS() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) HOMECHAINBURNADDRESS() (common.Address, error) { + return _NativeTokenRemote.Contract.HOMECHAINBURNADDRESS(&_NativeTokenRemote.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) MULTIHOPCALLGASPERWORD(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "MULTI_HOP_CALL_GAS_PER_WORD") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _NativeTokenRemote.Contract.MULTIHOPCALLGASPERWORD(&_NativeTokenRemote.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _NativeTokenRemote.Contract.MULTIHOPCALLGASPERWORD(&_NativeTokenRemote.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) MULTIHOPCALLREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "MULTI_HOP_CALL_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemote.Contract.MULTIHOPCALLREQUIREDGAS(&_NativeTokenRemote.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemote.Contract.MULTIHOPCALLREQUIREDGAS(&_NativeTokenRemote.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) MULTIHOPSENDREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "MULTI_HOP_SEND_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemote.Contract.MULTIHOPSENDREQUIREDGAS(&_NativeTokenRemote.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemote.Contract.MULTIHOPSENDREQUIREDGAS(&_NativeTokenRemote.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCaller) NATIVEMINTER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "NATIVE_MINTER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenRemote.Contract.NATIVEMINTER(&_NativeTokenRemote.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenRemote.Contract.NATIVEMINTER(&_NativeTokenRemote.CallOpts) +} + +// NATIVETOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0xa5717bc0. +// +// Solidity: function NATIVE_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCaller) NATIVETOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "NATIVE_TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// NATIVETOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0xa5717bc0. +// +// Solidity: function NATIVE_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteSession) NATIVETOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemote.Contract.NATIVETOKENREMOTESTORAGELOCATION(&_NativeTokenRemote.CallOpts) +} + +// NATIVETOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0xa5717bc0. +// +// Solidity: function NATIVE_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) NATIVETOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemote.Contract.NATIVETOKENREMOTESTORAGELOCATION(&_NativeTokenRemote.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) REGISTERREMOTEREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "REGISTER_REMOTE_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemote.Contract.REGISTERREMOTEREQUIREDGAS(&_NativeTokenRemote.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemote.Contract.REGISTERREMOTEREQUIREDGAS(&_NativeTokenRemote.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemote.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenRemote.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemote.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenRemote.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCaller) TOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemote.Contract.TOKENREMOTESTORAGELOCATION(&_NativeTokenRemote.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemote.Contract.TOKENREMOTESTORAGELOCATION(&_NativeTokenRemote.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _NativeTokenRemote.Contract.Allowance(&_NativeTokenRemote.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _NativeTokenRemote.Contract.Allowance(&_NativeTokenRemote.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) BalanceOf(account common.Address) (*big.Int, error) { + return _NativeTokenRemote.Contract.BalanceOf(&_NativeTokenRemote.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _NativeTokenRemote.Contract.BalanceOf(&_NativeTokenRemote.CallOpts, account) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) CalculateNumWords(opts *bind.CallOpts, payloadSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "calculateNumWords", payloadSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _NativeTokenRemote.Contract.CalculateNumWords(&_NativeTokenRemote.CallOpts, payloadSize) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _NativeTokenRemote.Contract.CalculateNumWords(&_NativeTokenRemote.CallOpts, payloadSize) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_NativeTokenRemote *NativeTokenRemoteCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_NativeTokenRemote *NativeTokenRemoteSession) Decimals() (uint8, error) { + return _NativeTokenRemote.Contract.Decimals(&_NativeTokenRemote.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) Decimals() (uint8, error) { + return _NativeTokenRemote.Contract.Decimals(&_NativeTokenRemote.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenRemote.Contract.GetBlockchainID(&_NativeTokenRemote.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenRemote.Contract.GetBlockchainID(&_NativeTokenRemote.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetInitialReserveImbalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getInitialReserveImbalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetInitialReserveImbalance() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetInitialReserveImbalance(&_NativeTokenRemote.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetInitialReserveImbalance() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetInitialReserveImbalance(&_NativeTokenRemote.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetIsCollateralized(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getIsCollateralized") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetIsCollateralized() (bool, error) { + return _NativeTokenRemote.Contract.GetIsCollateralized(&_NativeTokenRemote.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetIsCollateralized() (bool, error) { + return _NativeTokenRemote.Contract.GetIsCollateralized(&_NativeTokenRemote.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetMinTeleporterVersion(&_NativeTokenRemote.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetMinTeleporterVersion(&_NativeTokenRemote.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetMultiplyOnRemote(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getMultiplyOnRemote") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetMultiplyOnRemote() (bool, error) { + return _NativeTokenRemote.Contract.GetMultiplyOnRemote(&_NativeTokenRemote.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetMultiplyOnRemote() (bool, error) { + return _NativeTokenRemote.Contract.GetMultiplyOnRemote(&_NativeTokenRemote.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetTokenHomeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getTokenHomeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetTokenHomeAddress() (common.Address, error) { + return _NativeTokenRemote.Contract.GetTokenHomeAddress(&_NativeTokenRemote.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetTokenHomeAddress() (common.Address, error) { + return _NativeTokenRemote.Contract.GetTokenHomeAddress(&_NativeTokenRemote.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetTokenHomeBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getTokenHomeBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _NativeTokenRemote.Contract.GetTokenHomeBlockchainID(&_NativeTokenRemote.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _NativeTokenRemote.Contract.GetTokenHomeBlockchainID(&_NativeTokenRemote.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetTokenMultiplier(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getTokenMultiplier") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetTokenMultiplier() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetTokenMultiplier(&_NativeTokenRemote.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetTokenMultiplier() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetTokenMultiplier(&_NativeTokenRemote.CallOpts) +} + +// GetTotalMinted is a free data retrieval call binding the contract method 0x0ca1c5c9. +// +// Solidity: function getTotalMinted() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) GetTotalMinted(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "getTotalMinted") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTotalMinted is a free data retrieval call binding the contract method 0x0ca1c5c9. +// +// Solidity: function getTotalMinted() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) GetTotalMinted() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetTotalMinted(&_NativeTokenRemote.CallOpts) +} + +// GetTotalMinted is a free data retrieval call binding the contract method 0x0ca1c5c9. +// +// Solidity: function getTotalMinted() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) GetTotalMinted() (*big.Int, error) { + return _NativeTokenRemote.Contract.GetTotalMinted(&_NativeTokenRemote.CallOpts) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenRemote.Contract.IsTeleporterAddressPaused(&_NativeTokenRemote.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenRemote.Contract.IsTeleporterAddressPaused(&_NativeTokenRemote.CallOpts, teleporterAddress) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_NativeTokenRemote *NativeTokenRemoteCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_NativeTokenRemote *NativeTokenRemoteSession) Name() (string, error) { + return _NativeTokenRemote.Contract.Name(&_NativeTokenRemote.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) Name() (string, error) { + return _NativeTokenRemote.Contract.Name(&_NativeTokenRemote.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteSession) Owner() (common.Address, error) { + return _NativeTokenRemote.Contract.Owner(&_NativeTokenRemote.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) Owner() (common.Address, error) { + return _NativeTokenRemote.Contract.Owner(&_NativeTokenRemote.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_NativeTokenRemote *NativeTokenRemoteCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_NativeTokenRemote *NativeTokenRemoteSession) Symbol() (string, error) { + return _NativeTokenRemote.Contract.Symbol(&_NativeTokenRemote.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) Symbol() (string, error) { + return _NativeTokenRemote.Contract.Symbol(&_NativeTokenRemote.CallOpts) +} + +// TotalNativeAssetSupply is a free data retrieval call binding the contract method 0x1906529c. +// +// Solidity: function totalNativeAssetSupply() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) TotalNativeAssetSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "totalNativeAssetSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalNativeAssetSupply is a free data retrieval call binding the contract method 0x1906529c. +// +// Solidity: function totalNativeAssetSupply() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) TotalNativeAssetSupply() (*big.Int, error) { + return _NativeTokenRemote.Contract.TotalNativeAssetSupply(&_NativeTokenRemote.CallOpts) +} + +// TotalNativeAssetSupply is a free data retrieval call binding the contract method 0x1906529c. +// +// Solidity: function totalNativeAssetSupply() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) TotalNativeAssetSupply() (*big.Int, error) { + return _NativeTokenRemote.Contract.TotalNativeAssetSupply(&_NativeTokenRemote.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemote.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteSession) TotalSupply() (*big.Int, error) { + return _NativeTokenRemote.Contract.TotalSupply(&_NativeTokenRemote.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenRemote *NativeTokenRemoteCallerSession) TotalSupply() (*big.Int, error) { + return _NativeTokenRemote.Contract.TotalSupply(&_NativeTokenRemote.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Approve(&_NativeTokenRemote.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Approve(&_NativeTokenRemote.TransactOpts, spender, value) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "deposit") +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) Deposit() (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Deposit(&_NativeTokenRemote.TransactOpts) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Deposit() (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Deposit(&_NativeTokenRemote.TransactOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8f6cec88. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string nativeAssetSymbol, uint256 initialReserveImbalance, uint256 burnedFeesReportingRewardPercentage) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Initialize(opts *bind.TransactOpts, settings TokenRemoteSettings, nativeAssetSymbol string, initialReserveImbalance *big.Int, burnedFeesReportingRewardPercentage *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "initialize", settings, nativeAssetSymbol, initialReserveImbalance, burnedFeesReportingRewardPercentage) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8f6cec88. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string nativeAssetSymbol, uint256 initialReserveImbalance, uint256 burnedFeesReportingRewardPercentage) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) Initialize(settings TokenRemoteSettings, nativeAssetSymbol string, initialReserveImbalance *big.Int, burnedFeesReportingRewardPercentage *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Initialize(&_NativeTokenRemote.TransactOpts, settings, nativeAssetSymbol, initialReserveImbalance, burnedFeesReportingRewardPercentage) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8f6cec88. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string nativeAssetSymbol, uint256 initialReserveImbalance, uint256 burnedFeesReportingRewardPercentage) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Initialize(settings TokenRemoteSettings, nativeAssetSymbol string, initialReserveImbalance *big.Int, burnedFeesReportingRewardPercentage *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Initialize(&_NativeTokenRemote.TransactOpts, settings, nativeAssetSymbol, initialReserveImbalance, burnedFeesReportingRewardPercentage) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.PauseTeleporterAddress(&_NativeTokenRemote.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.PauseTeleporterAddress(&_NativeTokenRemote.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.ReceiveTeleporterMessage(&_NativeTokenRemote.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.ReceiveTeleporterMessage(&_NativeTokenRemote.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) RegisterWithHome(opts *bind.TransactOpts, feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "registerWithHome", feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.RegisterWithHome(&_NativeTokenRemote.TransactOpts, feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.RegisterWithHome(&_NativeTokenRemote.TransactOpts, feeInfo) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenRemote.Contract.RenounceOwnership(&_NativeTokenRemote.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenRemote.Contract.RenounceOwnership(&_NativeTokenRemote.TransactOpts) +} + +// ReportBurnedTxFees is a paid mutator transaction binding the contract method 0x55538c8b. +// +// Solidity: function reportBurnedTxFees(uint256 requiredGasLimit) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) ReportBurnedTxFees(opts *bind.TransactOpts, requiredGasLimit *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "reportBurnedTxFees", requiredGasLimit) +} + +// ReportBurnedTxFees is a paid mutator transaction binding the contract method 0x55538c8b. +// +// Solidity: function reportBurnedTxFees(uint256 requiredGasLimit) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) ReportBurnedTxFees(requiredGasLimit *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.ReportBurnedTxFees(&_NativeTokenRemote.TransactOpts, requiredGasLimit) +} + +// ReportBurnedTxFees is a paid mutator transaction binding the contract method 0x55538c8b. +// +// Solidity: function reportBurnedTxFees(uint256 requiredGasLimit) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) ReportBurnedTxFees(requiredGasLimit *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.ReportBurnedTxFees(&_NativeTokenRemote.TransactOpts, requiredGasLimit) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Send(opts *bind.TransactOpts, input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "send", input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Send(&_NativeTokenRemote.TransactOpts, input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Send(&_NativeTokenRemote.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "sendAndCall", input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.SendAndCall(&_NativeTokenRemote.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.SendAndCall(&_NativeTokenRemote.TransactOpts, input) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Transfer(&_NativeTokenRemote.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Transfer(&_NativeTokenRemote.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.TransferFrom(&_NativeTokenRemote.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.TransferFrom(&_NativeTokenRemote.TransactOpts, from, to, value) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.TransferOwnership(&_NativeTokenRemote.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.TransferOwnership(&_NativeTokenRemote.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.UnpauseTeleporterAddress(&_NativeTokenRemote.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.UnpauseTeleporterAddress(&_NativeTokenRemote.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.UpdateMinTeleporterVersion(&_NativeTokenRemote.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.UpdateMinTeleporterVersion(&_NativeTokenRemote.TransactOpts, version) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Withdraw(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.contract.Transact(opts, "withdraw", amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) Withdraw(amount *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Withdraw(&_NativeTokenRemote.TransactOpts, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Withdraw(amount *big.Int) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Withdraw(&_NativeTokenRemote.TransactOpts, amount) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _NativeTokenRemote.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Fallback(&_NativeTokenRemote.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Fallback(&_NativeTokenRemote.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemote.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteSession) Receive() (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Receive(&_NativeTokenRemote.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenRemote *NativeTokenRemoteTransactorSession) Receive() (*types.Transaction, error) { + return _NativeTokenRemote.Contract.Receive(&_NativeTokenRemote.TransactOpts) +} + +// NativeTokenRemoteApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the NativeTokenRemote contract. +type NativeTokenRemoteApprovalIterator struct { + Event *NativeTokenRemoteApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteApproval represents a Approval event raised by the NativeTokenRemote contract. +type NativeTokenRemoteApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*NativeTokenRemoteApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteApprovalIterator{contract: _NativeTokenRemote.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteApproval) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseApproval(log types.Log) (*NativeTokenRemoteApproval, error) { + event := new(NativeTokenRemoteApproval) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the NativeTokenRemote contract. +type NativeTokenRemoteCallFailedIterator struct { + Event *NativeTokenRemoteCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteCallFailed represents a CallFailed event raised by the NativeTokenRemote contract. +type NativeTokenRemoteCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenRemoteCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteCallFailedIterator{contract: _NativeTokenRemote.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteCallFailed) + if err := _NativeTokenRemote.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseCallFailed(log types.Log) (*NativeTokenRemoteCallFailed, error) { + event := new(NativeTokenRemoteCallFailed) + if err := _NativeTokenRemote.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the NativeTokenRemote contract. +type NativeTokenRemoteCallSucceededIterator struct { + Event *NativeTokenRemoteCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteCallSucceeded represents a CallSucceeded event raised by the NativeTokenRemote contract. +type NativeTokenRemoteCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenRemoteCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteCallSucceededIterator{contract: _NativeTokenRemote.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteCallSucceeded) + if err := _NativeTokenRemote.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseCallSucceeded(log types.Log) (*NativeTokenRemoteCallSucceeded, error) { + event := new(NativeTokenRemoteCallSucceeded) + if err := _NativeTokenRemote.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteDepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the NativeTokenRemote contract. +type NativeTokenRemoteDepositIterator struct { + Event *NativeTokenRemoteDeposit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteDepositIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteDepositIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteDepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteDeposit represents a Deposit event raised by the NativeTokenRemote contract. +type NativeTokenRemoteDeposit struct { + Sender common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposit is a free log retrieval operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterDeposit(opts *bind.FilterOpts, sender []common.Address) (*NativeTokenRemoteDepositIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "Deposit", senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteDepositIterator{contract: _NativeTokenRemote.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +// WatchDeposit is a free log subscription operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteDeposit, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "Deposit", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteDeposit) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposit is a log parse operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseDeposit(log types.Log) (*NativeTokenRemoteDeposit, error) { + event := new(NativeTokenRemoteDeposit) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the NativeTokenRemote contract. +type NativeTokenRemoteInitializedIterator struct { + Event *NativeTokenRemoteInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteInitialized represents a Initialized event raised by the NativeTokenRemote contract. +type NativeTokenRemoteInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterInitialized(opts *bind.FilterOpts) (*NativeTokenRemoteInitializedIterator, error) { + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NativeTokenRemoteInitializedIterator{contract: _NativeTokenRemote.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteInitialized) (event.Subscription, error) { + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteInitialized) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseInitialized(log types.Log) (*NativeTokenRemoteInitialized, error) { + event := new(NativeTokenRemoteInitialized) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the NativeTokenRemote contract. +type NativeTokenRemoteMinTeleporterVersionUpdatedIterator struct { + Event *NativeTokenRemoteMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the NativeTokenRemote contract. +type NativeTokenRemoteMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*NativeTokenRemoteMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteMinTeleporterVersionUpdatedIterator{contract: _NativeTokenRemote.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteMinTeleporterVersionUpdated) + if err := _NativeTokenRemote.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*NativeTokenRemoteMinTeleporterVersionUpdated, error) { + event := new(NativeTokenRemoteMinTeleporterVersionUpdated) + if err := _NativeTokenRemote.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the NativeTokenRemote contract. +type NativeTokenRemoteOwnershipTransferredIterator struct { + Event *NativeTokenRemoteOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteOwnershipTransferred represents a OwnershipTransferred event raised by the NativeTokenRemote contract. +type NativeTokenRemoteOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*NativeTokenRemoteOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteOwnershipTransferredIterator{contract: _NativeTokenRemote.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteOwnershipTransferred) + if err := _NativeTokenRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseOwnershipTransferred(log types.Log) (*NativeTokenRemoteOwnershipTransferred, error) { + event := new(NativeTokenRemoteOwnershipTransferred) + if err := _NativeTokenRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteReportBurnedTxFeesIterator is returned from FilterReportBurnedTxFees and is used to iterate over the raw logs and unpacked data for ReportBurnedTxFees events raised by the NativeTokenRemote contract. +type NativeTokenRemoteReportBurnedTxFeesIterator struct { + Event *NativeTokenRemoteReportBurnedTxFees // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteReportBurnedTxFeesIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteReportBurnedTxFees) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteReportBurnedTxFees) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteReportBurnedTxFeesIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteReportBurnedTxFeesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteReportBurnedTxFees represents a ReportBurnedTxFees event raised by the NativeTokenRemote contract. +type NativeTokenRemoteReportBurnedTxFees struct { + TeleporterMessageID [32]byte + FeesBurned *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterReportBurnedTxFees is a free log retrieval operation binding the contract event 0x0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a5. +// +// Solidity: event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterReportBurnedTxFees(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*NativeTokenRemoteReportBurnedTxFeesIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "ReportBurnedTxFees", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteReportBurnedTxFeesIterator{contract: _NativeTokenRemote.contract, event: "ReportBurnedTxFees", logs: logs, sub: sub}, nil +} + +// WatchReportBurnedTxFees is a free log subscription operation binding the contract event 0x0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a5. +// +// Solidity: event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchReportBurnedTxFees(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteReportBurnedTxFees, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "ReportBurnedTxFees", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteReportBurnedTxFees) + if err := _NativeTokenRemote.contract.UnpackLog(event, "ReportBurnedTxFees", 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 +} + +// ParseReportBurnedTxFees is a log parse operation binding the contract event 0x0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a5. +// +// Solidity: event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseReportBurnedTxFees(log types.Log) (*NativeTokenRemoteReportBurnedTxFees, error) { + event := new(NativeTokenRemoteReportBurnedTxFees) + if err := _NativeTokenRemote.contract.UnpackLog(event, "ReportBurnedTxFees", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the NativeTokenRemote contract. +type NativeTokenRemoteTeleporterAddressPausedIterator struct { + Event *NativeTokenRemoteTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the NativeTokenRemote contract. +type NativeTokenRemoteTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenRemoteTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteTeleporterAddressPausedIterator{contract: _NativeTokenRemote.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteTeleporterAddressPaused) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseTeleporterAddressPaused(log types.Log) (*NativeTokenRemoteTeleporterAddressPaused, error) { + event := new(NativeTokenRemoteTeleporterAddressPaused) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the NativeTokenRemote contract. +type NativeTokenRemoteTeleporterAddressUnpausedIterator struct { + Event *NativeTokenRemoteTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the NativeTokenRemote contract. +type NativeTokenRemoteTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenRemoteTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteTeleporterAddressUnpausedIterator{contract: _NativeTokenRemote.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteTeleporterAddressUnpaused) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*NativeTokenRemoteTeleporterAddressUnpaused, error) { + event := new(NativeTokenRemoteTeleporterAddressUnpaused) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the NativeTokenRemote contract. +type NativeTokenRemoteTokensAndCallSentIterator struct { + Event *NativeTokenRemoteTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteTokensAndCallSent represents a TokensAndCallSent event raised by the NativeTokenRemote contract. +type NativeTokenRemoteTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenRemoteTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteTokensAndCallSentIterator{contract: _NativeTokenRemote.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteTokensAndCallSent) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseTokensAndCallSent(log types.Log) (*NativeTokenRemoteTokensAndCallSent, error) { + event := new(NativeTokenRemoteTokensAndCallSent) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the NativeTokenRemote contract. +type NativeTokenRemoteTokensSentIterator struct { + Event *NativeTokenRemoteTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteTokensSent represents a TokensSent event raised by the NativeTokenRemote contract. +type NativeTokenRemoteTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenRemoteTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteTokensSentIterator{contract: _NativeTokenRemote.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteTokensSent) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseTokensSent(log types.Log) (*NativeTokenRemoteTokensSent, error) { + event := new(NativeTokenRemoteTokensSent) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the NativeTokenRemote contract. +type NativeTokenRemoteTokensWithdrawnIterator struct { + Event *NativeTokenRemoteTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteTokensWithdrawn represents a TokensWithdrawn event raised by the NativeTokenRemote contract. +type NativeTokenRemoteTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*NativeTokenRemoteTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteTokensWithdrawnIterator{contract: _NativeTokenRemote.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteTokensWithdrawn) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseTokensWithdrawn(log types.Log) (*NativeTokenRemoteTokensWithdrawn, error) { + event := new(NativeTokenRemoteTokensWithdrawn) + if err := _NativeTokenRemote.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the NativeTokenRemote contract. +type NativeTokenRemoteTransferIterator struct { + Event *NativeTokenRemoteTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteTransfer represents a Transfer event raised by the NativeTokenRemote contract. +type NativeTokenRemoteTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NativeTokenRemoteTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteTransferIterator{contract: _NativeTokenRemote.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteTransfer) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseTransfer(log types.Log) (*NativeTokenRemoteTransfer, error) { + event := new(NativeTokenRemoteTransfer) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteWithdrawalIterator is returned from FilterWithdrawal and is used to iterate over the raw logs and unpacked data for Withdrawal events raised by the NativeTokenRemote contract. +type NativeTokenRemoteWithdrawalIterator struct { + Event *NativeTokenRemoteWithdrawal // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteWithdrawalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteWithdrawalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteWithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteWithdrawal represents a Withdrawal event raised by the NativeTokenRemote contract. +type NativeTokenRemoteWithdrawal struct { + Sender common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawal is a free log retrieval operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) FilterWithdrawal(opts *bind.FilterOpts, sender []common.Address) (*NativeTokenRemoteWithdrawalIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.FilterLogs(opts, "Withdrawal", senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteWithdrawalIterator{contract: _NativeTokenRemote.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +// WatchWithdrawal is a free log subscription operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteWithdrawal, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemote.contract.WatchLogs(opts, "Withdrawal", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteWithdrawal) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawal is a log parse operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_NativeTokenRemote *NativeTokenRemoteFilterer) ParseWithdrawal(log types.Log) (*NativeTokenRemoteWithdrawal, error) { + event := new(NativeTokenRemoteWithdrawal) + if err := _NativeTokenRemote.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenRemote/NativeTokenRemoteUpgradeable/NativeTokenRemoteUpgradeable.go b/abi-bindings/go/ictt/TokenRemote/NativeTokenRemoteUpgradeable/NativeTokenRemoteUpgradeable.go new file mode 100644 index 000000000..9aaea45cb --- /dev/null +++ b/abi-bindings/go/ictt/TokenRemote/NativeTokenRemoteUpgradeable/NativeTokenRemoteUpgradeable.go @@ -0,0 +1,3770 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokenremoteupgradeable + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// TokenRemoteSettings is an auto generated low-level Go binding around an user-defined struct. +type TokenRemoteSettings struct { + TeleporterRegistryAddress common.Address + TeleporterManager common.Address + MinTeleporterVersion *big.Int + TokenHomeBlockchainID [32]byte + TokenHomeAddress common.Address + TokenHomeDecimals uint8 +} + +// NativeTokenRemoteUpgradeableMetaData contains all meta data concerning the NativeTokenRemoteUpgradeable contract. +var NativeTokenRemoteUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"enumICMInitializable\",\"name\":\"init\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feesBurned\",\"type\":\"uint256\"}],\"name\":\"ReportBurnedTxFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"BURNED_FOR_TRANSFER_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BURNED_TX_FEES_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"HOME_CHAIN_BURN_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_GAS_PER_WORD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_SEND_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NATIVE_MINTER\",\"outputs\":[{\"internalType\":\"contractINativeMinter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NATIVE_TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTER_REMOTE_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"payloadSize\",\"type\":\"uint256\"}],\"name\":\"calculateNumWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInitialReserveImbalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getIsCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMultiplyOnRemote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalMinted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"tokenHomeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"tokenHomeAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"tokenHomeDecimals\",\"type\":\"uint8\"}],\"internalType\":\"structTokenRemoteSettings\",\"name\":\"settings\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"nativeAssetSymbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"initialReserveImbalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"burnedFeesReportingRewardPercentage\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"registerWithHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"}],\"name\":\"reportBurnedTxFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"}],\"name\":\"sendAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalNativeAssetSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161511a38038061511a83398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b614fcd8061014d5f395ff3fe608060405260043610610280575f3560e01c8063715018a61161014e578063b8a46d02116100c0578063dd62ed3e11610079578063dd62ed3e14610736578063e0fd9cb814610755578063ed0ae4b014610452578063ef793e2a14610769578063f2fde38b1461077d578063f3f981d81461079c5761028f565b8063b8a46d02146106b9578063c3cd6927146106d8578063c452165e146106ec578063c868efaa14610703578063d0e30db01461028f578063d2cc7a70146107225761028f565b80638f6cec88116101125780638f6cec8814610608578063909a6ac01461062757806395d89b4114610647578063973142971461065b578063a5717bc01461067a578063a9059cbb1461069a5761028f565b8063715018a61461057b57806371717c181461058f5780637ee3779a146105a55780638bf2fa94146105b95780638da5cb5b146105cc5761028f565b80632e1a7d4d116101f25780634511243e116101ab5780634511243e146104b55780635507f3d1146104d457806355538c8b146104ea5780635eb99514146105095780636e6eef8d1461052857806370a082311461053b5761028f565b80632e1a7d4d146103e6578063313ce56714610405578063329c3e1214610420578063347212c41461045257806335cac1591461046e5780634213cf78146104a15761028f565b806315beb59f1161024457806315beb59f1461035557806318160ddd1461036a5780631906529c1461037e57806323b872dd14610392578063254ac160146103b15780632b0d8f18146103c75761028f565b806302a30c7d1461029757806306fdde03146102c05780630733c8c8146102e1578063095ea7b3146103035780630ca1c5c9146103225761028f565b3661028f5761028d6107bb565b005b61028d6107bb565b3480156102a2575f80fd5b506102ab6107fc565b60405190151581526020015b60405180910390f35b3480156102cb575f80fd5b506102d4610813565b6040516102b79190613f06565b3480156102ec575f80fd5b506102f56108d3565b6040519081526020016102b7565b34801561030e575f80fd5b506102ab61031d366004613f3c565b6108e7565b34801561032d575f80fd5b507f69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf501546102f5565b348015610360575f80fd5b506102f56105dc81565b348015610375575f80fd5b506102f5610900565b348015610389575f80fd5b506102f561091b565b34801561039d575f80fd5b506102ab6103ac366004613f66565b610972565b3480156103bc575f80fd5b506102f56201fbd081565b3480156103d2575f80fd5b5061028d6103e1366004613fa4565b610997565b3480156103f1575f80fd5b5061028d610400366004613fbf565b610a99565b348015610410575f80fd5b50604051601281526020016102b7565b34801561042b575f80fd5b5061043a6001600160991b0181565b6040516001600160a01b0390911681526020016102b7565b34801561045d575f80fd5b5061043a62010203600160981b0181565b348015610479575f80fd5b506102f57f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0081565b3480156104ac575f80fd5b506102f5610ae5565b3480156104c0575f80fd5b5061028d6104cf366004613fa4565b610af6565b3480156104df575f80fd5b506102f56205302081565b3480156104f5575f80fd5b5061028d610504366004613fbf565b610be5565b348015610514575f80fd5b5061028d610523366004613fbf565b610ef7565b61028d610536366004613fd6565b610f08565b348015610546575f80fd5b506102f5610555366004613fa4565b6001600160a01b03165f9081525f80516020614f18833981519152602052604090205490565b348015610586575f80fd5b5061028d610f36565b34801561059a575f80fd5b506102f56205573081565b3480156105b0575f80fd5b506102ab610f47565b61028d6105c736600461400d565b610f5e565b3480156105d7575f80fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031661043a565b348015610613575f80fd5b5061028d61062236600461414d565b610f8c565b348015610632575f80fd5b506102f55f80516020614f7883398151915281565b348015610652575f80fd5b506102d461109e565b348015610666575f80fd5b506102ab610675366004613fa4565b6110dc565b348015610685575f80fd5b506102f55f80516020614f5883398151915281565b3480156106a5575f80fd5b506102ab6106b4366004613f3c565b6110f5565b3480156106c4575f80fd5b5061028d6106d3366004614217565b611102565b3480156106e3575f80fd5b5061043a611276565b3480156106f7575f80fd5b5061043a600160981b81565b34801561070e575f80fd5b5061028d61071d366004614227565b611293565b34801561072d575f80fd5b506102f5611450565b348015610741575f80fd5b506102f56107503660046142a8565b611465565b348015610760575f80fd5b506102f56114ae565b348015610774575f80fd5b506102f56114c2565b348015610788575f80fd5b5061028d610797366004613fa4565b6114d6565b3480156107a7575f80fd5b506102f56107b6366004613fbf565b611510565b60405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a26107fa3334611526565b565b5f8061080661155e565b6006015460ff1692915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0380546060915f80516020614f1883398151915291610851906142df565b80601f016020809104026020016040519081016040528092919081815260200182805461087d906142df565b80156108c85780601f1061089f576101008083540402835291602001916108c8565b820191905f5260205f20905b8154815290600101906020018083116108ab57829003601f168201915b505050505091505090565b5f806108dd61155e565b6003015492915050565b5f336108f4818585611582565b60019150505b92915050565b5f805f80516020614f188339815191525b6002015492915050565b5f5f80516020614f588339815191528161094462010203600160981b0131600160981b31614325565b90505f61094f6114c2565b836001015461095e9190614325565b905061096a8282614338565b935050505090565b5f3361097f858285611594565b61098a8585856115f1565b60019150505b9392505050565b5f80516020614f788339815191526109ad61164e565b6001600160a01b0382166109dc5760405162461bcd60e51b81526004016109d39061434b565b60405180910390fd5b6109e68183611656565b15610a495760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b60648201526084016109d3565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b60405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a2610ad83382611677565b610ae233826116ab565b50565b5f80610aef61155e565b5492915050565b5f80516020614f78833981519152610b0c61164e565b6001600160a01b038216610b325760405162461bcd60e51b81526004016109d39061434b565b610b3c8183611656565b610b9a5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b60648201526084016109d3565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b5f80516020614f388339815191528054600114610c145760405162461bcd60e51b81526004016109d390614399565b600281557f69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf502545f80516020614f5883398151915290600160981b31908111610cd25760405162461bcd60e51b8152602060048201526044602482018190527f4e6174697665546f6b656e52656d6f74653a206275726e206164647265737320908201527f62616c616e6365206e6f742067726561746572207468616e206c6173742072656064820152631c1bdc9d60e21b608482015260a4016109d3565b5f826002015482610ce39190614338565b90505f6064845f015483610cf791906143dd565b610d0191906143f4565b90505f610d0e8284614338565b6002860185905590508115610d3157610d27308361173e565b610d313083611526565b5f610d4b610d3d6108d3565b610d45610f47565b846117eb565b11610db55760405162461bcd60e51b815260206004820152603460248201527f4e6174697665546f6b656e52656d6f74653a207a65726f207363616c6564206160448201527336b7bab73a103a37903932b837b93a10313ab93760611b60648201526084016109d3565b604080518082018252600181528151808301835262010203600160981b018152602080820185905292515f9380840192610df192909101614427565b60405160208183030381529060405281525090505f610eac6040518060c00160405280610e1c6114ae565b8152602001610e29611276565b6001600160a01b0316815260408051808201825230815260208181018a905283015281018c90526060015f5b604051908082528060200260200182016040528015610e7e578160200160208202803683370190505b50815260200184604051602001610e959190614447565b604051602081830303815290604052815250611800565b9050807f0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a584604051610ee091815260200190565b60405180910390a250506001909555505050505050565b610eff61164e565b610ae28161191b565b610f106107fc565b610f2c5760405162461bcd60e51b81526004016109d390614489565b610ae28134611ab3565b610f3e611b2a565b6107fa5f611b85565b5f80610f5161155e565b6004015460ff1692915050565b610f666107fc565b610f825760405162461bcd60e51b81526004016109d390614489565b610ae28134611bf5565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610fd05750825b90505f826001600160401b03166001148015610feb5750303b155b905081158015610ff9575080155b156110175760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561104157845460ff60401b1916600160401b1785555b61104d89898989611c61565b831561109357845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060915f80516020614f1883398151915291610851906142df565b5f5f80516020614f788339815191526109908184611656565b5f336108f48185856115f1565b5f61110b61155e565b6006810154909150610100900460ff16156111685760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e52656d6f74653a20616c726561647920726567697374657265640060448201526064016109d3565b604080516060808201835260058401548252600284015460ff600160a01b820481166020808601918252600160a81b9093048216858701908152865180880188525f808252885188518188015293518516848a015291519093168286015286518083039095018552608090910190955280820192909252919290916111fd906111f390870187613fa4565b8660200135611cf1565b6040805160c0810182526001870154815260028701546001600160a01b03166020808301919091528251808401845293945061126e939192830191908190611247908b018b613fa4565b6001600160a01b0316815260209081018690529082526201fbd0908201526040015f610e55565b505050505050565b5f8061128061155e565b600201546001600160a01b031692915050565b61129b611d38565b5f5f80516020614f7883398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611306573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061132a91906144d8565b10156113915760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b60648201526084016109d3565b61139b8133611656565b156114015760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b60648201526084016109d3565b611441858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611d8292505050565b5061144a611f99565b50505050565b5f805f80516020614f78833981519152610911565b6001600160a01b039182165f9081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b5f806114b861155e565b6001015492915050565b5f806114cc61155e565b6005015492915050565b6114de611b2a565b6001600160a01b03811661150757604051631e4fbdf760e01b81525f60048201526024016109d3565b610ae281611b85565b5f600561151e83601f614325565b901c92915050565b6001600160a01b03821661154f5760405163ec442f0560e01b81525f60048201526024016109d3565b61155a5f8383611fc3565b5050565b7f600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef0090565b61158f83838360016120fc565b505050565b5f61159f8484611465565b90505f19811461144a57818110156115e357604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016109d3565b61144a84848484035f6120fc565b6001600160a01b03831661161a57604051634b637e8f60e11b81525f60048201526024016109d3565b6001600160a01b0382166116435760405163ec442f0560e01b81525f60048201526024016109d3565b61158f838383611fc3565b6107fa611b2a565b6001600160a01b03165f908152600191909101602052604090205460ff1690565b6001600160a01b0382166116a057604051634b637e8f60e11b81525f60048201526024016109d3565b61155a825f83611fc3565b804710156116ce5760405163cd78605960e01b81523060048201526024016109d3565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611717576040519150601f19603f3d011682016040523d82523d5f602084013e61171c565b606091505b505090508061158f57604051630a12f52160e11b815260040160405180910390fd5b7f69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf50180545f80516020614f588339815191529183915f9061177f908490614325565b90915550506040516327ad555d60e11b81526001600160a01b0384166004820152602481018390526001600160991b0190634f5aaaba906044015f604051808303815f87803b1580156117d0575f80fd5b505af11580156117e2573d5f803e3d5ffd5b50505050505050565b5f6117f88484845f6121df565b949350505050565b5f8061180a61220f565b604084015160200151909150156118af576040830151516001600160a01b031661188c5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b60648201526084016109d3565b6040830151602081015190516118af916001600160a01b039091169083906122ff565b604051630624488560e41b81526001600160a01b038216906362448850906118db9086906004016144ef565b6020604051808303815f875af11580156118f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061099091906144d8565b5f80516020614f7883398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa15801561196f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199391906144d8565b600283015490915081841115611a055760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016109d3565b808411611a7a5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016109d3565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b5f80516020614f388339815191528054600114611ae25760405162461bcd60e51b81526004016109d390614399565b600281555f611aef61155e565b9050611afa84612386565b6001810154843503611b1657611b1084846125c0565b50611b22565b611b1084846127e4565b505b600190555050565b33611b5c7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146107fa5760405163118cdaa760e01b81523360048201526024016109d3565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f80516020614f388339815191528054600114611c245760405162461bcd60e51b81526004016109d390614399565b600281555f611c3161155e565b9050611c3c84612a85565b6001810154843503611c5757611c528484612b70565b611b20565b611b208484612cdf565b611c69612ea5565b815f03611cd25760405162461bcd60e51b815260206004820152603160248201527f4e6174697665546f6b656e52656d6f74653a207a65726f20696e697469616c206044820152707265736572766520696d62616c616e636560781b60648201526084016109d3565b611cdc8384612eee565b611ce884836012612f00565b61144a81612f31565b5f815f03611d0057505f6108fa565b306001600160a01b03841603611d2d57611d1b333084611594565b611d263330846115f1565b50806108fa565b610990833384612fa8565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00805460011901611d7c57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f611d8b61155e565b905080600101548414611df25760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20696e76616c696420736f7572636520626c6f636044820152681ad8da185a5b88125160ba1b60648201526084016109d3565b60028101546001600160a01b03848116911614611e645760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a20696e76616c6964206f726967696e2073656e646044820152696572206164647265737360b01b60648201526084016109d3565b5f82806020019051810190611e7991906145e8565b6006830154909150610100900460ff161580611e9a5750600682015460ff16155b15611eb15760068201805461ffff19166101011790555b600181516004811115611ec657611ec6614413565b03611efd575f8160200151806020019051810190611ee49190614670565b9050611ef7815f0151826020015161310b565b50611f92565b600281516004811115611f1257611f12614413565b03611f40575f8160200151806020019051810190611f3091906146a8565b9050611ef7818260800151613158565b60405162461bcd60e51b815260206004820152602160248201527f546f6b656e52656d6f74653a20696e76616c6964206d657373616765207479706044820152606560f81b60648201526084016109d3565b5050505050565b5f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b6001905550565b5f80516020614f188339815191526001600160a01b038416611ffd5781816002015f828254611ff29190614325565b9091555061206d9050565b6001600160a01b0384165f908152602082905260409020548281101561204f5760405163391434e360e21b81526001600160a01b038616600482015260248101829052604481018490526064016109d3565b6001600160a01b0385165f9081526020839052604090209083900390555b6001600160a01b03831661208b5760028101805483900390556120a9565b6001600160a01b0383165f9081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516120ee91815260200190565b60405180910390a350505050565b5f80516020614f188339815191526001600160a01b0385166121335760405163e602df0560e01b81525f60048201526024016109d3565b6001600160a01b03841661215c57604051634a1406b160e11b81525f60048201526024016109d3565b6001600160a01b038086165f90815260018301602090815260408083209388168352929052208390558115611f9257836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925856040516121d091815260200190565b60405180910390a35050505050565b5f811515841515036121fc576121f585846143dd565b90506117f8565b61220685846143f4565b95945050505050565b5f80516020614f7883398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015612269573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061228d9190614772565b90506122998282611656565b156108fa5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b60648201526084016109d3565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa15801561234c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061237091906144d8565b905061144a84846123818585614325565b613282565b80356123a45760405162461bcd60e51b81526004016109d39061478d565b5f6123b56040830160208401613fa4565b6001600160a01b0316036123db5760405162461bcd60e51b81526004016109d3906147d8565b5f6123ec6060830160408401613fa4565b6001600160a01b0316036124575760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420636f6e7460448201526b72616374206164647265737360a01b60648201526084016109d3565b5f81608001351161247a5760405162461bcd60e51b81526004016109d390614835565b5f8160a00135116124db5760405162461bcd60e51b815260206004820152602560248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e7420676173206044820152641b1a5b5a5d60da1b60648201526084016109d3565b80608001358160a00135106125435760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a20696e76616c696420726563697069656e742067604482015267185cc81b1a5b5a5d60c21b60648201526084016109d3565b5f612555610100830160e08401613fa4565b6001600160a01b031603610ae25760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a207a65726f2066616c6c6261636b20726563697060448201526b69656e74206164647265737360a01b60648201526084016109d3565b5f6125c961155e565b90506125f96125de6040850160208601613fa4565b6101408501356125f460e0870160c08801613fa4565b61333f565b5f6126218361261061012087016101008801613fa4565b86610120013587610140013561343c565b6040805180820190915291945091505f908060028152602001604051806101000160405280865f01548152602001306001600160a01b031681526020016126653390565b6001600160a01b0316815260200161268360608a0160408b01613fa4565b6001600160a01b03168152602081018890526040016126a560608a018a614879565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a089013560208201526040016126f96101008a0160e08b01613fa4565b6001600160a01b0316905260405161271491906020016148bb565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92612796928201908061276e6101208c016101008d01613fa4565b6001600160a01b03168152602090810188905290825260808a0135908201526040015f610e55565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b1688886040516127d49291906149c2565b60405180910390a3505050505050565b5f6127ed61155e565b905061281983356128046040860160208701613fa4565b61281460e0870160c08801613fa4565b6134ff565b5f6128308361261061012087016101008801613fa4565b6040805180820190915291945091505f90806004815260200160405180610160016040528061285c3390565b6001600160a01b03168152602001885f013581526020018860200160208101906128869190613fa4565b6001600160a01b031681526020016128a460608a0160408b01613fa4565b6001600160a01b03168152602081018890526040016128c660608a018a614879565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060a0890135602082015260400161291a6101008a0160e08b01613fa4565b6001600160a01b031681526080890135602082015260400161294260e08a0160c08b01613fa4565b6001600160a01b03168152610140890135602091820152604051612967929101614ad0565b60408051601f19818403018152919052905290505f6105dc61299661298f6060890189614879565b9050611510565b6129a091906143dd565b6129ad9062055730614325565b6040805160c0810182526001870154815260028701546001600160a01b03166020820152815180830183529293505f92612a3692820190806129f76101208d016101008e01613fa4565b6001600160a01b031681526020908101899052908252818101869052604080515f815280830182528184015251606090920191610e9591889101614447565b9050336001600160a01b0316817f5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b168989604051612a749291906149c2565b60405180910390a350505050505050565b5f612a966060830160408401613fa4565b6001600160a01b031603612af85760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a207a65726f20726563697069656e74206164647260448201526265737360e81b60648201526084016109d3565b5f8160c0013511612b1b5760405162461bcd60e51b81526004016109d390614835565b8035612b395760405162461bcd60e51b81526004016109d39061478d565b5f612b4a6040830160208401613fa4565b6001600160a01b031603610ae25760405162461bcd60e51b81526004016109d3906147d8565b5f612b7961155e565b9050612ba4612b8e6040850160208601613fa4565b60a08501356125f4610100870160e08801613fa4565b5f612bc883612bb96080870160608801613fa4565b86608001358760a0013561343c565b6040805180820190915291945091505f9080600181526020016040518060400160405280886040016020810190612bff9190613fa4565b6001600160a01b0316815260200187815250604051602001612c219190614427565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92612ca19282019080612c7960808c0160608d01613fa4565b6001600160a01b03168152602090810188905290825260c08a0135908201526040015f610e55565b9050336001600160a01b0316817f93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb5288886040516127d4929190614bad565b5f612ce861155e565b9050612d108335612cff6040860160208701613fa4565b612814610100870160e08801613fa4565b5f612d2583612bb96080870160608801613fa4565b60408051808201825260038152815160e081018352883581529396509193505f9260208084019282820191612d5e918b01908b01613fa4565b6001600160a01b03168152602001612d7c60608a0160408b01613fa4565b6001600160a01b031681526020810188905260a0890135604082015260c08901356060820152608001612db66101008a0160e08b01613fa4565b6001600160a01b03169052604051612e269190602001815181526020808301516001600160a01b0390811691830191909152604080840151821690830152606080840151908301526080808401519083015260a0808401519083015260c092830151169181019190915260e00190565b60408051601f198184030181529181529152805160c0810182526001860154815260028601546001600160a01b03166020820152815180830183529293505f92612ca19282019080612e7e60808c0160608d01613fa4565b6001600160a01b03168152602090810188905290825262053020908201526040015f610e55565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166107fa57604051631afcd79f60e31b815260040160405180910390fd5b612ef6612ea5565b61155a828261359d565b612f08612ea5565b612f1e835f0151846020015185604001516135ed565b612f26613608565b61158f838383613618565b612f39612ea5565b60648110612f975760405162461bcd60e51b815260206004820152602560248201527f4e6174697665546f6b656e52656d6f74653a20696e76616c69642070657263656044820152646e7461676560d81b60648201526084016109d3565b5f80516020614f5883398151915255565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa158015612fee573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061301291906144d8565b90506130296001600160a01b03861685308661393c565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa15801561306d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061309191906144d8565b90508181116130f75760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016109d3565b6131018282614338565b9695505050505050565b816001600160a01b03167f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b8260405161314691815260200190565b60405180910390a261155a828261173e565b613162308261173e565b5f825f0151836020015184604001518560a001516040516024016131899493929190614c4c565b60408051601f198184030181529190526020810180516001600160e01b031663161b12ff60e11b17905260c084015160608501519192505f916131cf9190859085613975565b905080156132235783606001516001600160a01b03167f104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff48460405161321691815260200190565b60405180910390a261144a565b83606001516001600160a01b03167fb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb08460405161326291815260200190565b60405180910390a260e084015161144a906001600160a01b0316846116ab565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526132d38482613a45565b61144a576040516001600160a01b0384811660248301525f604483015261333591869182169063095ea7b3906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613ae2565b61144a8482613ae2565b5f61334861155e565b60028101549091506001600160a01b0385811691161461337a5760405162461bcd60e51b81526004016109d390614c7d565b82156133d45760405162461bcd60e51b815260206004820152602360248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f207365636f6e646172792060448201526266656560e81b60648201526084016109d3565b6001600160a01b0382161561144a5760405162461bcd60e51b815260206004820152602860248201527f546f6b656e52656d6f74653a206e6f6e2d7a65726f206d756c74692d686f702060448201526766616c6c6261636b60c01b60648201526084016109d3565b5f805f61344761155e565b905061345287613b43565b965061345e8686611cf1565b600382015460048301549196506134789160ff16866117eb565b60038201546004830154613490919060ff168a6117eb565b116134f25760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e52656d6f74653a20696e73756666696369656e7420746f6b656e7360448201526b103a37903a3930b739b332b960a11b60648201526084016109d3565b5094959294509192505050565b5f61350861155e565b8054909150840361353b57306001600160a01b0384160361353b5760405162461bcd60e51b81526004016109d390614c7d565b6001600160a01b03821661144a5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f206d756c74692d686f702066616c6c6044820152636261636b60e01b60648201526084016109d3565b6135a5612ea5565b5f80516020614f188339815191527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace036135de8482614d1e565b506004810161144a8382614d1e565b6135f5612ea5565b6135ff8382613b5b565b61158f82613b7d565b613610612ea5565b6107fa613b8e565b613620612ea5565b5f61362961155e565b90506005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561366e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061369291906144d8565b815560608401516136f85760405162461bcd60e51b815260206004820152602a60248201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d6520626c6f60448201526918dad8da185a5b88125160b21b60648201526084016109d3565b80546060850151036137725760405162461bcd60e51b815260206004820152603b60248201527f546f6b656e52656d6f74653a2063616e6e6f74206465706c6f7920746f20736160448201527f6d6520626c6f636b636861696e20617320746f6b656e20686f6d65000000000060648201526084016109d3565b60808401516001600160a01b03166137d85760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a207a65726f20746f6b656e20686f6d65206164646044820152637265737360e01b60648201526084016109d3565b60128460a0015160ff1611156138425760405162461bcd60e51b815260206004820152602960248201527f546f6b656e52656d6f74653a20746f6b656e20686f6d6520646563696d616c73604482015268040e8dede40d0d2ced60bb1b60648201526084016109d3565b60128260ff1611156138a25760405162461bcd60e51b8152602060048201526024808201527f546f6b656e52656d6f74653a20746f6b656e20646563696d616c7320746f6f206044820152630d0d2ced60e31b60648201526084016109d3565b60608401516001820155608084015160028201805460058401869055600684018054871560ff1990911617905560a08701516001600160a01b039093166001600160a81b031990911617600160a01b60ff808516919091029190911760ff60a81b1916600160a81b9186169190910217905561391e9083613ba2565b60048301805460ff1916911515919091179055600390910155505050565b6040516001600160a01b03848116602483015283811660448301526064820183905261144a9186918216906323b872dd90608401613303565b5f845a10156139c65760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e73756666696369656e7420676173000000000060448201526064016109d3565b83471015613a165760405162461bcd60e51b815260206004820152601d60248201527f43616c6c5574696c733a20696e73756666696369656e742076616c756500000060448201526064016109d3565b826001600160a01b03163b5f03613a2e57505f6117f8565b5f805f84516020860188888bf19695505050505050565b5f805f846001600160a01b031684604051613a609190614dd9565b5f604051808303815f865af19150503d805f8114613a99576040519150601f19603f3d011682016040523d82523d5f602084013e613a9e565b606091505b5091509150818015613ac8575080511580613ac8575080806020019051810190613ac89190614df4565b80156122065750505050506001600160a01b03163b151590565b5f613af66001600160a01b03841683613bec565b905080515f14158015613b1a575080806020019051810190613b189190614df4565b155b1561158f57604051635274afe760e01b81526001600160a01b03841660048201526024016109d3565b5f613b5762010203600160981b01836116ab565b5090565b613b63612ea5565b613b6b613bf9565b613b73613c09565b61155a8282613c11565b613b85612ea5565b610ae281613d95565b5f5f80516020614f38833981519152611fbc565b5f8060ff808516908416118181613bc557613bbd8587614e13565b60ff16613bd3565b613bcf8686614e13565b60ff165b613bde90600a614f0c565b9350909150505b9250929050565b606061099083835f613d9d565b613c01612ea5565b6107fa613e2c565b6107fa612ea5565b613c19612ea5565b6001600160a01b038216613c955760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084016109d3565b5f5f80516020614f7883398151915290505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ce7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613d0b91906144d8565b11613d735760405162461bcd60e51b815260206004820152603260248201527f54656c65706f7274657252656769737472794170703a20696e76616c69642054604482015271656c65706f7274657220726567697374727960701b60648201526084016109d3565b81546001600160a01b0319166001600160a01b03821617825561144a8361191b565b6114de612ea5565b606081471015613dc25760405163cd78605960e01b81523060048201526024016109d3565b5f80856001600160a01b03168486604051613ddd9190614dd9565b5f6040518083038185875af1925050503d805f8114613e17576040519150601f19603f3d011682016040523d82523d5f602084013e613e1c565b606091505b5091509150613101868383613e34565b611f99612ea5565b606082613e4957613e4482613e90565b610990565b8151158015613e6057506001600160a01b0384163b155b15613e8957604051639996b31560e01b81526001600160a01b03851660048201526024016109d3565b5080610990565b805115613ea05780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f5b83811015613ed3578181015183820152602001613ebb565b50505f910152565b5f8151808452613ef2816020860160208601613eb9565b601f01601f19169290920160200192915050565b602081525f6109906020830184613edb565b6001600160a01b0381168114610ae2575f80fd5b8035613f3781613f18565b919050565b5f8060408385031215613f4d575f80fd5b8235613f5881613f18565b946020939093013593505050565b5f805f60608486031215613f78575f80fd5b8335613f8381613f18565b92506020840135613f9381613f18565b929592945050506040919091013590565b5f60208284031215613fb4575f80fd5b813561099081613f18565b5f60208284031215613fcf575f80fd5b5035919050565b5f60208284031215613fe6575f80fd5b81356001600160401b03811115613ffb575f80fd5b82016101608185031215610990575f80fd5b5f610100828403121561401e575f80fd5b50919050565b634e487b7160e01b5f52604160045260245ffd5b60405160c081016001600160401b038111828210171561405a5761405a614024565b60405290565b604080519081016001600160401b038111828210171561405a5761405a614024565b60405161010081016001600160401b038111828210171561405a5761405a614024565b604051601f8201601f191681016001600160401b03811182821017156140cd576140cd614024565b604052919050565b5f6001600160401b038211156140ed576140ed614024565b50601f01601f191660200190565b5f82601f83011261410a575f80fd5b813561411d614118826140d5565b6140a5565b818152846020838601011115614131575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80848603610120811215614162575f80fd5b60c081121561416f575f80fd5b50614178614038565b853561418381613f18565b8152602086013561419381613f18565b80602083015250604086013560408201526060860135606082015260808601356141bc81613f18565b608082015260a086013560ff811681146141d4575f80fd5b60a0820152935060c08501356001600160401b038111156141f3575f80fd5b6141ff878288016140fb565b949794965050505060e0830135926101000135919050565b5f6040828403121561401e575f80fd5b5f805f806060858703121561423a575f80fd5b84359350602085013561424c81613f18565b925060408501356001600160401b0380821115614267575f80fd5b818701915087601f83011261427a575f80fd5b813581811115614288575f80fd5b886020828501011115614299575f80fd5b95989497505060200194505050565b5f80604083850312156142b9575f80fd5b82356142c481613f18565b915060208301356142d481613f18565b809150509250929050565b600181811c908216806142f357607f821691505b60208210810361401e57634e487b7160e01b5f52602260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156108fa576108fa614311565b818103818111156108fa576108fa614311565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b60208082526024908201527f53656e645265656e7472616e637947756172643a2073656e64207265656e7472604082015263616e637960e01b606082015260800190565b80820281158282048414176108fa576108fa614311565b5f8261440e57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffd5b81516001600160a01b0316815260208083015190820152604081016108fa565b602081525f82516005811061446a57634e487b7160e01b5f52602160045260245ffd5b8060208401525060208301516040808401526117f86060840182613edb565b6020808252602f908201527f4e6174697665546f6b656e52656d6f74653a20636f6e747261637420756e646560408201526e1c98dbdb1b185d195c985b1a5e9959608a1b606082015260800190565b5f602082840312156144e8575f80fd5b5051919050565b6020808252825182820152828101516001600160a01b039081166040808501919091528401518051821660608501528083015160808501525f929161010085019190606087015160a0870152608087015160e060c08801528051938490528401925f92506101208701905b8084101561457c5784518316825293850193600193909301929085019061455a565b5060a0880151878203601f190160e0890152945061459a8186613edb565b98975050505050505050565b5f82601f8301126145b5575f80fd5b81516145c3614118826140d5565b8181528460208386010111156145d7575f80fd5b6117f8826020830160208701613eb9565b5f602082840312156145f8575f80fd5b81516001600160401b038082111561460e575f80fd5b9083019060408286031215614621575f80fd5b614629614060565b825160058110614637575f80fd5b815260208301518281111561464a575f80fd5b614656878286016145a6565b60208301525095945050505050565b8051613f3781613f18565b5f60408284031215614680575f80fd5b614688614060565b825161469381613f18565b81526020928301519281019290925250919050565b5f602082840312156146b8575f80fd5b81516001600160401b03808211156146ce575f80fd5b9083019061010082860312156146e2575f80fd5b6146ea614082565b825181526146fa60208401614665565b602082015261470b60408401614665565b604082015261471c60608401614665565b60608201526080830151608082015260a08301518281111561473c575f80fd5b614748878286016145a6565b60a08301525060c083015160c082015261476460e08401614665565b60e082015295945050505050565b5f60208284031215614782575f80fd5b815161099081613f18565b6020808252602b908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20626c60408201526a1bd8dad8da185a5b88125160aa1b606082015260800190565b60208082526037908201527f546f6b656e52656d6f74653a207a65726f2064657374696e6174696f6e20746f60408201527f6b656e207472616e736665727265722061646472657373000000000000000000606082015260800190565b60208082526024908201527f546f6b656e52656d6f74653a207a65726f20726571756972656420676173206c6040820152631a5b5a5d60e21b606082015260800190565b5f808335601e1984360301811261488e575f80fd5b8301803591506001600160401b038211156148a7575f80fd5b602001915036819003821315613be5575f80fd5b60208152815160208201525f602083015160018060a01b0380821660408501528060408601511660608501525050606083015161490360808401826001600160a01b03169052565b50608083015160a083015260a08301516101008060c085015261492a610120850183613edb565b915060c085015160e085015260e085015161494f828601826001600160a01b03169052565b5090949350505050565b5f808335601e1984360301811261496e575f80fd5b83016020810192503590506001600160401b0381111561498c575f80fd5b803603821315613be5575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60408152823560408201525f6149da60208501613f2c565b6001600160a01b031660608301526149f460408501613f2c565b6001600160a01b03166080830152614a0f6060850185614959565b6101608060a0860152614a276101a08601838561499a565b9250608087013560c086015260a087013560e0860152614a4960c08801613f2c565b9150610100614a62818701846001600160a01b03169052565b614a6e60e08901613f2c565b9250610120614a87818801856001600160a01b03169052565b614a92828a01613f2c565b93506101409150614aad828801856001600160a01b03169052565b880135918601919091529095013561018084015260209092019290925292915050565b60208152614aea6020820183516001600160a01b03169052565b602082015160408201525f6040830151614b0f60608401826001600160a01b03169052565b5060608301516001600160a01b038116608084015250608083015160a083015260a08301516101608060c0850152614b4b610180850183613edb565b915060c085015160e085015260e0850151610100614b73818701836001600160a01b03169052565b860151610120868101919091528601519050610140614b9c818701836001600160a01b03169052565b959095015193019290925250919050565b8235815261012081016020840135614bc481613f18565b6001600160a01b039081166020840152604085013590614be382613f18565b166040830152614bf560608501613f2c565b6001600160a01b0381166060840152506080840135608083015260a084013560a083015260c084013560c0830152614c2f60e08501613f2c565b6001600160a01b031660e083015261010090910191909152919050565b8481526001600160a01b038481166020830152831660408201526080606082018190525f9061310190830184613edb565b6020808252603a908201527f546f6b656e52656d6f74653a20696e76616c69642064657374696e6174696f6e60408201527f20746f6b656e207472616e736665727265722061646472657373000000000000606082015260800190565b601f82111561158f57805f5260205f20601f840160051c81016020851015614cff5750805b601f840160051c820191505b81811015611f92575f8155600101614d0b565b81516001600160401b03811115614d3757614d37614024565b614d4b81614d4584546142df565b84614cda565b602080601f831160018114614d7e575f8415614d675750858301515b5f19600386901b1c1916600185901b17855561126e565b5f85815260208120601f198616915b82811015614dac57888601518255948401946001909101908401614d8d565b5085821015614dc957878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f8251614dea818460208701613eb9565b9190910192915050565b5f60208284031215614e04575f80fd5b81518015158114610990575f80fd5b60ff82811682821603908111156108fa576108fa614311565b600181815b80851115614e6657815f1904821115614e4c57614e4c614311565b80851615614e5957918102915b93841c9390800290614e31565b509250929050565b5f82614e7c575060016108fa565b81614e8857505f6108fa565b8160018114614e9e5760028114614ea857614ec4565b60019150506108fa565b60ff841115614eb957614eb9614311565b50506001821b6108fa565b5060208310610133831016604e8410600b8410161715614ee7575081810a6108fa565b614ef18383614e2c565b805f1904821115614f0457614f04614311565b029392505050565b5f6109908383614e6e56fe52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00d2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c750069a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf500de77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a2646970667358221220a72e560c7911904401023a50b4c72c841ba63eeb5569c77b744acfa83d06350c64736f6c63430008190033", +} + +// NativeTokenRemoteUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenRemoteUpgradeableMetaData.ABI instead. +var NativeTokenRemoteUpgradeableABI = NativeTokenRemoteUpgradeableMetaData.ABI + +// NativeTokenRemoteUpgradeableBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenRemoteUpgradeableMetaData.Bin instead. +var NativeTokenRemoteUpgradeableBin = NativeTokenRemoteUpgradeableMetaData.Bin + +// DeployNativeTokenRemoteUpgradeable deploys a new Ethereum contract, binding an instance of NativeTokenRemoteUpgradeable to it. +func DeployNativeTokenRemoteUpgradeable(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *NativeTokenRemoteUpgradeable, error) { + parsed, err := NativeTokenRemoteUpgradeableMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NativeTokenRemoteUpgradeableBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenRemoteUpgradeable{NativeTokenRemoteUpgradeableCaller: NativeTokenRemoteUpgradeableCaller{contract: contract}, NativeTokenRemoteUpgradeableTransactor: NativeTokenRemoteUpgradeableTransactor{contract: contract}, NativeTokenRemoteUpgradeableFilterer: NativeTokenRemoteUpgradeableFilterer{contract: contract}}, nil +} + +// NativeTokenRemoteUpgradeable is an auto generated Go binding around an Ethereum contract. +type NativeTokenRemoteUpgradeable struct { + NativeTokenRemoteUpgradeableCaller // Read-only binding to the contract + NativeTokenRemoteUpgradeableTransactor // Write-only binding to the contract + NativeTokenRemoteUpgradeableFilterer // Log filterer for contract events +} + +// NativeTokenRemoteUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenRemoteUpgradeableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenRemoteUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenRemoteUpgradeableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenRemoteUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenRemoteUpgradeableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenRemoteUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenRemoteUpgradeableSession struct { + Contract *NativeTokenRemoteUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenRemoteUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenRemoteUpgradeableCallerSession struct { + Contract *NativeTokenRemoteUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenRemoteUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenRemoteUpgradeableTransactorSession struct { + Contract *NativeTokenRemoteUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenRemoteUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenRemoteUpgradeableRaw struct { + Contract *NativeTokenRemoteUpgradeable // Generic contract binding to access the raw methods on +} + +// NativeTokenRemoteUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenRemoteUpgradeableCallerRaw struct { + Contract *NativeTokenRemoteUpgradeableCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenRemoteUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenRemoteUpgradeableTransactorRaw struct { + Contract *NativeTokenRemoteUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenRemoteUpgradeable creates a new instance of NativeTokenRemoteUpgradeable, bound to a specific deployed contract. +func NewNativeTokenRemoteUpgradeable(address common.Address, backend bind.ContractBackend) (*NativeTokenRemoteUpgradeable, error) { + contract, err := bindNativeTokenRemoteUpgradeable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeable{NativeTokenRemoteUpgradeableCaller: NativeTokenRemoteUpgradeableCaller{contract: contract}, NativeTokenRemoteUpgradeableTransactor: NativeTokenRemoteUpgradeableTransactor{contract: contract}, NativeTokenRemoteUpgradeableFilterer: NativeTokenRemoteUpgradeableFilterer{contract: contract}}, nil +} + +// NewNativeTokenRemoteUpgradeableCaller creates a new read-only instance of NativeTokenRemoteUpgradeable, bound to a specific deployed contract. +func NewNativeTokenRemoteUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenRemoteUpgradeableCaller, error) { + contract, err := bindNativeTokenRemoteUpgradeable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableCaller{contract: contract}, nil +} + +// NewNativeTokenRemoteUpgradeableTransactor creates a new write-only instance of NativeTokenRemoteUpgradeable, bound to a specific deployed contract. +func NewNativeTokenRemoteUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenRemoteUpgradeableTransactor, error) { + contract, err := bindNativeTokenRemoteUpgradeable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableTransactor{contract: contract}, nil +} + +// NewNativeTokenRemoteUpgradeableFilterer creates a new log filterer instance of NativeTokenRemoteUpgradeable, bound to a specific deployed contract. +func NewNativeTokenRemoteUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenRemoteUpgradeableFilterer, error) { + contract, err := bindNativeTokenRemoteUpgradeable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableFilterer{contract: contract}, nil +} + +// bindNativeTokenRemoteUpgradeable binds a generic wrapper to an already deployed contract. +func bindNativeTokenRemoteUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenRemoteUpgradeableMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenRemoteUpgradeable.Contract.NativeTokenRemoteUpgradeableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.NativeTokenRemoteUpgradeableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.NativeTokenRemoteUpgradeableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenRemoteUpgradeable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.contract.Transact(opts, method, params...) +} + +// BURNEDFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0x347212c4. +// +// Solidity: function BURNED_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) BURNEDFORTRANSFERADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "BURNED_FOR_TRANSFER_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNEDFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0x347212c4. +// +// Solidity: function BURNED_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) BURNEDFORTRANSFERADDRESS() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.BURNEDFORTRANSFERADDRESS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// BURNEDFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0x347212c4. +// +// Solidity: function BURNED_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) BURNEDFORTRANSFERADDRESS() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.BURNEDFORTRANSFERADDRESS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) BURNEDTXFEESADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "BURNED_TX_FEES_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.BURNEDTXFEESADDRESS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.BURNEDTXFEESADDRESS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// HOMECHAINBURNADDRESS is a free data retrieval call binding the contract method 0xed0ae4b0. +// +// Solidity: function HOME_CHAIN_BURN_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) HOMECHAINBURNADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "HOME_CHAIN_BURN_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// HOMECHAINBURNADDRESS is a free data retrieval call binding the contract method 0xed0ae4b0. +// +// Solidity: function HOME_CHAIN_BURN_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) HOMECHAINBURNADDRESS() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.HOMECHAINBURNADDRESS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// HOMECHAINBURNADDRESS is a free data retrieval call binding the contract method 0xed0ae4b0. +// +// Solidity: function HOME_CHAIN_BURN_ADDRESS() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) HOMECHAINBURNADDRESS() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.HOMECHAINBURNADDRESS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) MULTIHOPCALLGASPERWORD(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "MULTI_HOP_CALL_GAS_PER_WORD") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.MULTIHOPCALLGASPERWORD(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.MULTIHOPCALLGASPERWORD(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) MULTIHOPCALLREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "MULTI_HOP_CALL_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.MULTIHOPCALLREQUIREDGAS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.MULTIHOPCALLREQUIREDGAS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) MULTIHOPSENDREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "MULTI_HOP_SEND_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.MULTIHOPSENDREQUIREDGAS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.MULTIHOPSENDREQUIREDGAS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) NATIVEMINTER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "NATIVE_MINTER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.NATIVEMINTER(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.NATIVEMINTER(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// NATIVETOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0xa5717bc0. +// +// Solidity: function NATIVE_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) NATIVETOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "NATIVE_TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// NATIVETOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0xa5717bc0. +// +// Solidity: function NATIVE_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) NATIVETOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.NATIVETOKENREMOTESTORAGELOCATION(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// NATIVETOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0xa5717bc0. +// +// Solidity: function NATIVE_TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) NATIVETOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.NATIVETOKENREMOTESTORAGELOCATION(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) REGISTERREMOTEREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "REGISTER_REMOTE_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.REGISTERREMOTEREQUIREDGAS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.REGISTERREMOTEREQUIREDGAS(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) TOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.TOKENREMOTESTORAGELOCATION(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.TOKENREMOTESTORAGELOCATION(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.Allowance(&_NativeTokenRemoteUpgradeable.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.Allowance(&_NativeTokenRemoteUpgradeable.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) BalanceOf(account common.Address) (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.BalanceOf(&_NativeTokenRemoteUpgradeable.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.BalanceOf(&_NativeTokenRemoteUpgradeable.CallOpts, account) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) CalculateNumWords(opts *bind.CallOpts, payloadSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "calculateNumWords", payloadSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.CalculateNumWords(&_NativeTokenRemoteUpgradeable.CallOpts, payloadSize) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.CalculateNumWords(&_NativeTokenRemoteUpgradeable.CallOpts, payloadSize) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Decimals() (uint8, error) { + return _NativeTokenRemoteUpgradeable.Contract.Decimals(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) Decimals() (uint8, error) { + return _NativeTokenRemoteUpgradeable.Contract.Decimals(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetBlockchainID(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetBlockchainID() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetBlockchainID(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetInitialReserveImbalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getInitialReserveImbalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetInitialReserveImbalance() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetInitialReserveImbalance(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetInitialReserveImbalance() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetInitialReserveImbalance(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetIsCollateralized(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getIsCollateralized") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetIsCollateralized() (bool, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetIsCollateralized(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetIsCollateralized() (bool, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetIsCollateralized(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetMinTeleporterVersion(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetMinTeleporterVersion(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetMultiplyOnRemote(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getMultiplyOnRemote") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetMultiplyOnRemote() (bool, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetMultiplyOnRemote(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetMultiplyOnRemote() (bool, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetMultiplyOnRemote(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetTokenHomeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getTokenHomeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetTokenHomeAddress() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTokenHomeAddress(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetTokenHomeAddress() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTokenHomeAddress(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetTokenHomeBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getTokenHomeBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTokenHomeBlockchainID(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTokenHomeBlockchainID(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetTokenMultiplier(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getTokenMultiplier") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetTokenMultiplier() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTokenMultiplier(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetTokenMultiplier() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTokenMultiplier(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTotalMinted is a free data retrieval call binding the contract method 0x0ca1c5c9. +// +// Solidity: function getTotalMinted() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) GetTotalMinted(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "getTotalMinted") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTotalMinted is a free data retrieval call binding the contract method 0x0ca1c5c9. +// +// Solidity: function getTotalMinted() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) GetTotalMinted() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTotalMinted(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// GetTotalMinted is a free data retrieval call binding the contract method 0x0ca1c5c9. +// +// Solidity: function getTotalMinted() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) GetTotalMinted() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.GetTotalMinted(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenRemoteUpgradeable.Contract.IsTeleporterAddressPaused(&_NativeTokenRemoteUpgradeable.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _NativeTokenRemoteUpgradeable.Contract.IsTeleporterAddressPaused(&_NativeTokenRemoteUpgradeable.CallOpts, teleporterAddress) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Name() (string, error) { + return _NativeTokenRemoteUpgradeable.Contract.Name(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) Name() (string, error) { + return _NativeTokenRemoteUpgradeable.Contract.Name(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Owner() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.Owner(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) Owner() (common.Address, error) { + return _NativeTokenRemoteUpgradeable.Contract.Owner(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Symbol() (string, error) { + return _NativeTokenRemoteUpgradeable.Contract.Symbol(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) Symbol() (string, error) { + return _NativeTokenRemoteUpgradeable.Contract.Symbol(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TotalNativeAssetSupply is a free data retrieval call binding the contract method 0x1906529c. +// +// Solidity: function totalNativeAssetSupply() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) TotalNativeAssetSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "totalNativeAssetSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalNativeAssetSupply is a free data retrieval call binding the contract method 0x1906529c. +// +// Solidity: function totalNativeAssetSupply() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) TotalNativeAssetSupply() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.TotalNativeAssetSupply(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TotalNativeAssetSupply is a free data retrieval call binding the contract method 0x1906529c. +// +// Solidity: function totalNativeAssetSupply() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) TotalNativeAssetSupply() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.TotalNativeAssetSupply(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenRemoteUpgradeable.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) TotalSupply() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.TotalSupply(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableCallerSession) TotalSupply() (*big.Int, error) { + return _NativeTokenRemoteUpgradeable.Contract.TotalSupply(&_NativeTokenRemoteUpgradeable.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Approve(&_NativeTokenRemoteUpgradeable.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Approve(&_NativeTokenRemoteUpgradeable.TransactOpts, spender, value) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "deposit") +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Deposit() (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Deposit(&_NativeTokenRemoteUpgradeable.TransactOpts) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Deposit() (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Deposit(&_NativeTokenRemoteUpgradeable.TransactOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8f6cec88. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string nativeAssetSymbol, uint256 initialReserveImbalance, uint256 burnedFeesReportingRewardPercentage) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Initialize(opts *bind.TransactOpts, settings TokenRemoteSettings, nativeAssetSymbol string, initialReserveImbalance *big.Int, burnedFeesReportingRewardPercentage *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "initialize", settings, nativeAssetSymbol, initialReserveImbalance, burnedFeesReportingRewardPercentage) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8f6cec88. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string nativeAssetSymbol, uint256 initialReserveImbalance, uint256 burnedFeesReportingRewardPercentage) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Initialize(settings TokenRemoteSettings, nativeAssetSymbol string, initialReserveImbalance *big.Int, burnedFeesReportingRewardPercentage *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Initialize(&_NativeTokenRemoteUpgradeable.TransactOpts, settings, nativeAssetSymbol, initialReserveImbalance, burnedFeesReportingRewardPercentage) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8f6cec88. +// +// Solidity: function initialize((address,address,uint256,bytes32,address,uint8) settings, string nativeAssetSymbol, uint256 initialReserveImbalance, uint256 burnedFeesReportingRewardPercentage) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Initialize(settings TokenRemoteSettings, nativeAssetSymbol string, initialReserveImbalance *big.Int, burnedFeesReportingRewardPercentage *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Initialize(&_NativeTokenRemoteUpgradeable.TransactOpts, settings, nativeAssetSymbol, initialReserveImbalance, burnedFeesReportingRewardPercentage) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.PauseTeleporterAddress(&_NativeTokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.PauseTeleporterAddress(&_NativeTokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.ReceiveTeleporterMessage(&_NativeTokenRemoteUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.ReceiveTeleporterMessage(&_NativeTokenRemoteUpgradeable.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) RegisterWithHome(opts *bind.TransactOpts, feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "registerWithHome", feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.RegisterWithHome(&_NativeTokenRemoteUpgradeable.TransactOpts, feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.RegisterWithHome(&_NativeTokenRemoteUpgradeable.TransactOpts, feeInfo) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.RenounceOwnership(&_NativeTokenRemoteUpgradeable.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.RenounceOwnership(&_NativeTokenRemoteUpgradeable.TransactOpts) +} + +// ReportBurnedTxFees is a paid mutator transaction binding the contract method 0x55538c8b. +// +// Solidity: function reportBurnedTxFees(uint256 requiredGasLimit) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) ReportBurnedTxFees(opts *bind.TransactOpts, requiredGasLimit *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "reportBurnedTxFees", requiredGasLimit) +} + +// ReportBurnedTxFees is a paid mutator transaction binding the contract method 0x55538c8b. +// +// Solidity: function reportBurnedTxFees(uint256 requiredGasLimit) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) ReportBurnedTxFees(requiredGasLimit *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.ReportBurnedTxFees(&_NativeTokenRemoteUpgradeable.TransactOpts, requiredGasLimit) +} + +// ReportBurnedTxFees is a paid mutator transaction binding the contract method 0x55538c8b. +// +// Solidity: function reportBurnedTxFees(uint256 requiredGasLimit) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) ReportBurnedTxFees(requiredGasLimit *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.ReportBurnedTxFees(&_NativeTokenRemoteUpgradeable.TransactOpts, requiredGasLimit) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Send(opts *bind.TransactOpts, input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "send", input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Send(&_NativeTokenRemoteUpgradeable.TransactOpts, input) +} + +// Send is a paid mutator transaction binding the contract method 0x8bf2fa94. +// +// Solidity: function send((bytes32,address,address,address,uint256,uint256,uint256,address) input) payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Send(input SendTokensInput) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Send(&_NativeTokenRemoteUpgradeable.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) SendAndCall(opts *bind.TransactOpts, input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "sendAndCall", input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.SendAndCall(&_NativeTokenRemoteUpgradeable.TransactOpts, input) +} + +// SendAndCall is a paid mutator transaction binding the contract method 0x6e6eef8d. +// +// Solidity: function sendAndCall((bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input) payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) SendAndCall(input SendAndCallInput) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.SendAndCall(&_NativeTokenRemoteUpgradeable.TransactOpts, input) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Transfer(&_NativeTokenRemoteUpgradeable.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Transfer(&_NativeTokenRemoteUpgradeable.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.TransferFrom(&_NativeTokenRemoteUpgradeable.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.TransferFrom(&_NativeTokenRemoteUpgradeable.TransactOpts, from, to, value) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.TransferOwnership(&_NativeTokenRemoteUpgradeable.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.TransferOwnership(&_NativeTokenRemoteUpgradeable.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.UnpauseTeleporterAddress(&_NativeTokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.UnpauseTeleporterAddress(&_NativeTokenRemoteUpgradeable.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.UpdateMinTeleporterVersion(&_NativeTokenRemoteUpgradeable.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.UpdateMinTeleporterVersion(&_NativeTokenRemoteUpgradeable.TransactOpts, version) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Withdraw(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.Transact(opts, "withdraw", amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Withdraw(amount *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Withdraw(&_NativeTokenRemoteUpgradeable.TransactOpts, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Withdraw(amount *big.Int) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Withdraw(&_NativeTokenRemoteUpgradeable.TransactOpts, amount) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Fallback(&_NativeTokenRemoteUpgradeable.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Fallback(&_NativeTokenRemoteUpgradeable.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableSession) Receive() (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Receive(&_NativeTokenRemoteUpgradeable.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableTransactorSession) Receive() (*types.Transaction, error) { + return _NativeTokenRemoteUpgradeable.Contract.Receive(&_NativeTokenRemoteUpgradeable.TransactOpts) +} + +// NativeTokenRemoteUpgradeableApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableApprovalIterator struct { + Event *NativeTokenRemoteUpgradeableApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableApproval represents a Approval event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*NativeTokenRemoteUpgradeableApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableApprovalIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableApproval) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseApproval(log types.Log) (*NativeTokenRemoteUpgradeableApproval, error) { + event := new(NativeTokenRemoteUpgradeableApproval) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableCallFailedIterator struct { + Event *NativeTokenRemoteUpgradeableCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableCallFailed represents a CallFailed event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenRemoteUpgradeableCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableCallFailedIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableCallFailed) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseCallFailed(log types.Log) (*NativeTokenRemoteUpgradeableCallFailed, error) { + event := new(NativeTokenRemoteUpgradeableCallFailed) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableCallSucceededIterator struct { + Event *NativeTokenRemoteUpgradeableCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableCallSucceeded represents a CallSucceeded event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*NativeTokenRemoteUpgradeableCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableCallSucceededIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableCallSucceeded) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseCallSucceeded(log types.Log) (*NativeTokenRemoteUpgradeableCallSucceeded, error) { + event := new(NativeTokenRemoteUpgradeableCallSucceeded) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableDepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableDepositIterator struct { + Event *NativeTokenRemoteUpgradeableDeposit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableDepositIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableDepositIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableDepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableDeposit represents a Deposit event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableDeposit struct { + Sender common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposit is a free log retrieval operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterDeposit(opts *bind.FilterOpts, sender []common.Address) (*NativeTokenRemoteUpgradeableDepositIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "Deposit", senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableDepositIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +// WatchDeposit is a free log subscription operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableDeposit, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "Deposit", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableDeposit) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposit is a log parse operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseDeposit(log types.Log) (*NativeTokenRemoteUpgradeableDeposit, error) { + event := new(NativeTokenRemoteUpgradeableDeposit) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableInitializedIterator struct { + Event *NativeTokenRemoteUpgradeableInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableInitialized represents a Initialized event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*NativeTokenRemoteUpgradeableInitializedIterator, error) { + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableInitializedIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableInitialized) (event.Subscription, error) { + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableInitialized) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseInitialized(log types.Log) (*NativeTokenRemoteUpgradeableInitialized, error) { + event := new(NativeTokenRemoteUpgradeableInitialized) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator struct { + Event *NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*NativeTokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableMinTeleporterVersionUpdatedIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated, error) { + event := new(NativeTokenRemoteUpgradeableMinTeleporterVersionUpdated) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableOwnershipTransferredIterator struct { + Event *NativeTokenRemoteUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*NativeTokenRemoteUpgradeableOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableOwnershipTransferredIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableOwnershipTransferred) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*NativeTokenRemoteUpgradeableOwnershipTransferred, error) { + event := new(NativeTokenRemoteUpgradeableOwnershipTransferred) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableReportBurnedTxFeesIterator is returned from FilterReportBurnedTxFees and is used to iterate over the raw logs and unpacked data for ReportBurnedTxFees events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableReportBurnedTxFeesIterator struct { + Event *NativeTokenRemoteUpgradeableReportBurnedTxFees // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableReportBurnedTxFeesIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableReportBurnedTxFees) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableReportBurnedTxFees) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableReportBurnedTxFeesIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableReportBurnedTxFeesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableReportBurnedTxFees represents a ReportBurnedTxFees event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableReportBurnedTxFees struct { + TeleporterMessageID [32]byte + FeesBurned *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterReportBurnedTxFees is a free log retrieval operation binding the contract event 0x0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a5. +// +// Solidity: event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterReportBurnedTxFees(opts *bind.FilterOpts, teleporterMessageID [][32]byte) (*NativeTokenRemoteUpgradeableReportBurnedTxFeesIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "ReportBurnedTxFees", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableReportBurnedTxFeesIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "ReportBurnedTxFees", logs: logs, sub: sub}, nil +} + +// WatchReportBurnedTxFees is a free log subscription operation binding the contract event 0x0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a5. +// +// Solidity: event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchReportBurnedTxFees(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableReportBurnedTxFees, teleporterMessageID [][32]byte) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "ReportBurnedTxFees", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableReportBurnedTxFees) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "ReportBurnedTxFees", 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 +} + +// ParseReportBurnedTxFees is a log parse operation binding the contract event 0x0832c643b65d6d3724ed14ac3a655fbc7cae54fb010918b2c2f70ef6b1bb94a5. +// +// Solidity: event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseReportBurnedTxFees(log types.Log) (*NativeTokenRemoteUpgradeableReportBurnedTxFees, error) { + event := new(NativeTokenRemoteUpgradeableReportBurnedTxFees) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "ReportBurnedTxFees", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTeleporterAddressPausedIterator struct { + Event *NativeTokenRemoteUpgradeableTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenRemoteUpgradeableTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableTeleporterAddressPausedIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableTeleporterAddressPaused) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseTeleporterAddressPaused(log types.Log) (*NativeTokenRemoteUpgradeableTeleporterAddressPaused, error) { + event := new(NativeTokenRemoteUpgradeableTeleporterAddressPaused) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTeleporterAddressUnpausedIterator struct { + Event *NativeTokenRemoteUpgradeableTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*NativeTokenRemoteUpgradeableTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableTeleporterAddressUnpausedIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*NativeTokenRemoteUpgradeableTeleporterAddressUnpaused, error) { + event := new(NativeTokenRemoteUpgradeableTeleporterAddressUnpaused) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTokensAndCallSentIterator struct { + Event *NativeTokenRemoteUpgradeableTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableTokensAndCallSent represents a TokensAndCallSent event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenRemoteUpgradeableTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableTokensAndCallSentIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableTokensAndCallSent) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseTokensAndCallSent(log types.Log) (*NativeTokenRemoteUpgradeableTokensAndCallSent, error) { + event := new(NativeTokenRemoteUpgradeableTokensAndCallSent) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTokensSentIterator struct { + Event *NativeTokenRemoteUpgradeableTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableTokensSent represents a TokensSent event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*NativeTokenRemoteUpgradeableTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableTokensSentIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableTokensSent) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseTokensSent(log types.Log) (*NativeTokenRemoteUpgradeableTokensSent, error) { + event := new(NativeTokenRemoteUpgradeableTokensSent) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTokensWithdrawnIterator struct { + Event *NativeTokenRemoteUpgradeableTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableTokensWithdrawn represents a TokensWithdrawn event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*NativeTokenRemoteUpgradeableTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableTokensWithdrawnIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableTokensWithdrawn) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseTokensWithdrawn(log types.Log) (*NativeTokenRemoteUpgradeableTokensWithdrawn, error) { + event := new(NativeTokenRemoteUpgradeableTokensWithdrawn) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTransferIterator struct { + Event *NativeTokenRemoteUpgradeableTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableTransfer represents a Transfer event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*NativeTokenRemoteUpgradeableTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableTransferIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableTransfer) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseTransfer(log types.Log) (*NativeTokenRemoteUpgradeableTransfer, error) { + event := new(NativeTokenRemoteUpgradeableTransfer) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenRemoteUpgradeableWithdrawalIterator is returned from FilterWithdrawal and is used to iterate over the raw logs and unpacked data for Withdrawal events raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableWithdrawalIterator struct { + Event *NativeTokenRemoteUpgradeableWithdrawal // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenRemoteUpgradeableWithdrawalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenRemoteUpgradeableWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenRemoteUpgradeableWithdrawalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenRemoteUpgradeableWithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenRemoteUpgradeableWithdrawal represents a Withdrawal event raised by the NativeTokenRemoteUpgradeable contract. +type NativeTokenRemoteUpgradeableWithdrawal struct { + Sender common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawal is a free log retrieval operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) FilterWithdrawal(opts *bind.FilterOpts, sender []common.Address) (*NativeTokenRemoteUpgradeableWithdrawalIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.FilterLogs(opts, "Withdrawal", senderRule) + if err != nil { + return nil, err + } + return &NativeTokenRemoteUpgradeableWithdrawalIterator{contract: _NativeTokenRemoteUpgradeable.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +// WatchWithdrawal is a free log subscription operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *NativeTokenRemoteUpgradeableWithdrawal, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _NativeTokenRemoteUpgradeable.contract.WatchLogs(opts, "Withdrawal", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenRemoteUpgradeableWithdrawal) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawal is a log parse operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_NativeTokenRemoteUpgradeable *NativeTokenRemoteUpgradeableFilterer) ParseWithdrawal(log types.Log) (*NativeTokenRemoteUpgradeableWithdrawal, error) { + event := new(NativeTokenRemoteUpgradeableWithdrawal) + if err := _NativeTokenRemoteUpgradeable.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/TokenRemote/TokenRemote/TokenRemote.go b/abi-bindings/go/ictt/TokenRemote/TokenRemote/TokenRemote.go new file mode 100644 index 000000000..e5cf2c47e --- /dev/null +++ b/abi-bindings/go/ictt/TokenRemote/TokenRemote/TokenRemote.go @@ -0,0 +1,2361 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package tokenremote + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// SendAndCallInput is an auto generated low-level Go binding around an user-defined struct. +type SendAndCallInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + RecipientContract common.Address + RecipientPayload []byte + RequiredGasLimit *big.Int + RecipientGasLimit *big.Int + MultiHopFallback common.Address + FallbackRecipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int +} + +// SendTokensInput is an auto generated low-level Go binding around an user-defined struct. +type SendTokensInput struct { + DestinationBlockchainID [32]byte + DestinationTokenTransferrerAddress common.Address + Recipient common.Address + PrimaryFeeTokenAddress common.Address + PrimaryFee *big.Int + SecondaryFee *big.Int + RequiredGasLimit *big.Int + MultiHopFallback common.Address +} + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// TokenRemoteMetaData contains all meta data concerning the TokenRemote contract. +var TokenRemoteMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"CallSucceeded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipientPayload\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"recipientGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"fallbackRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structSendAndCallInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensAndCallSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"teleporterMessageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"primaryFeeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"primaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"multiHopFallback\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structSendTokensInput\",\"name\":\"input\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_GAS_PER_WORD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_CALL_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MULTI_HOP_SEND_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTER_REMOTE_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_REMOTE_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"payloadSize\",\"type\":\"uint256\"}],\"name\":\"calculateNumWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getInitialReserveImbalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getIsCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMultiplyOnRemote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenHomeBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"registerWithHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// TokenRemoteABI is the input ABI used to generate the binding from. +// Deprecated: Use TokenRemoteMetaData.ABI instead. +var TokenRemoteABI = TokenRemoteMetaData.ABI + +// TokenRemote is an auto generated Go binding around an Ethereum contract. +type TokenRemote struct { + TokenRemoteCaller // Read-only binding to the contract + TokenRemoteTransactor // Write-only binding to the contract + TokenRemoteFilterer // Log filterer for contract events +} + +// TokenRemoteCaller is an auto generated read-only Go binding around an Ethereum contract. +type TokenRemoteCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenRemoteTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TokenRemoteTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenRemoteFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TokenRemoteFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenRemoteSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TokenRemoteSession struct { + Contract *TokenRemote // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenRemoteCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TokenRemoteCallerSession struct { + Contract *TokenRemoteCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TokenRemoteTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TokenRemoteTransactorSession struct { + Contract *TokenRemoteTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenRemoteRaw is an auto generated low-level Go binding around an Ethereum contract. +type TokenRemoteRaw struct { + Contract *TokenRemote // Generic contract binding to access the raw methods on +} + +// TokenRemoteCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TokenRemoteCallerRaw struct { + Contract *TokenRemoteCaller // Generic read-only contract binding to access the raw methods on +} + +// TokenRemoteTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TokenRemoteTransactorRaw struct { + Contract *TokenRemoteTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTokenRemote creates a new instance of TokenRemote, bound to a specific deployed contract. +func NewTokenRemote(address common.Address, backend bind.ContractBackend) (*TokenRemote, error) { + contract, err := bindTokenRemote(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TokenRemote{TokenRemoteCaller: TokenRemoteCaller{contract: contract}, TokenRemoteTransactor: TokenRemoteTransactor{contract: contract}, TokenRemoteFilterer: TokenRemoteFilterer{contract: contract}}, nil +} + +// NewTokenRemoteCaller creates a new read-only instance of TokenRemote, bound to a specific deployed contract. +func NewTokenRemoteCaller(address common.Address, caller bind.ContractCaller) (*TokenRemoteCaller, error) { + contract, err := bindTokenRemote(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TokenRemoteCaller{contract: contract}, nil +} + +// NewTokenRemoteTransactor creates a new write-only instance of TokenRemote, bound to a specific deployed contract. +func NewTokenRemoteTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenRemoteTransactor, error) { + contract, err := bindTokenRemote(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TokenRemoteTransactor{contract: contract}, nil +} + +// NewTokenRemoteFilterer creates a new log filterer instance of TokenRemote, bound to a specific deployed contract. +func NewTokenRemoteFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenRemoteFilterer, error) { + contract, err := bindTokenRemote(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TokenRemoteFilterer{contract: contract}, nil +} + +// bindTokenRemote binds a generic wrapper to an already deployed contract. +func bindTokenRemote(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TokenRemoteMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TokenRemote *TokenRemoteRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenRemote.Contract.TokenRemoteCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TokenRemote *TokenRemoteRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenRemote.Contract.TokenRemoteTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TokenRemote *TokenRemoteRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenRemote.Contract.TokenRemoteTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TokenRemote *TokenRemoteCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenRemote.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TokenRemote *TokenRemoteTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenRemote.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TokenRemote *TokenRemoteTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenRemote.Contract.contract.Transact(opts, method, params...) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_TokenRemote *TokenRemoteCaller) MULTIHOPCALLGASPERWORD(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "MULTI_HOP_CALL_GAS_PER_WORD") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_TokenRemote *TokenRemoteSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _TokenRemote.Contract.MULTIHOPCALLGASPERWORD(&_TokenRemote.CallOpts) +} + +// MULTIHOPCALLGASPERWORD is a free data retrieval call binding the contract method 0x15beb59f. +// +// Solidity: function MULTI_HOP_CALL_GAS_PER_WORD() view returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) MULTIHOPCALLGASPERWORD() (*big.Int, error) { + return _TokenRemote.Contract.MULTIHOPCALLGASPERWORD(&_TokenRemote.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteCaller) MULTIHOPCALLREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "MULTI_HOP_CALL_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _TokenRemote.Contract.MULTIHOPCALLREQUIREDGAS(&_TokenRemote.CallOpts) +} + +// MULTIHOPCALLREQUIREDGAS is a free data retrieval call binding the contract method 0x71717c18. +// +// Solidity: function MULTI_HOP_CALL_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) MULTIHOPCALLREQUIREDGAS() (*big.Int, error) { + return _TokenRemote.Contract.MULTIHOPCALLREQUIREDGAS(&_TokenRemote.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteCaller) MULTIHOPSENDREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "MULTI_HOP_SEND_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _TokenRemote.Contract.MULTIHOPSENDREQUIREDGAS(&_TokenRemote.CallOpts) +} + +// MULTIHOPSENDREQUIREDGAS is a free data retrieval call binding the contract method 0x5507f3d1. +// +// Solidity: function MULTI_HOP_SEND_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) MULTIHOPSENDREQUIREDGAS() (*big.Int, error) { + return _TokenRemote.Contract.MULTIHOPSENDREQUIREDGAS(&_TokenRemote.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteCaller) REGISTERREMOTEREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "REGISTER_REMOTE_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _TokenRemote.Contract.REGISTERREMOTEREQUIREDGAS(&_TokenRemote.CallOpts) +} + +// REGISTERREMOTEREQUIREDGAS is a free data retrieval call binding the contract method 0x254ac160. +// +// Solidity: function REGISTER_REMOTE_REQUIRED_GAS() view returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) REGISTERREMOTEREQUIREDGAS() (*big.Int, error) { + return _TokenRemote.Contract.REGISTERREMOTEREQUIREDGAS(&_TokenRemote.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TokenRemote *TokenRemoteCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TokenRemote *TokenRemoteSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _TokenRemote.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_TokenRemote.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TokenRemote *TokenRemoteCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _TokenRemote.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_TokenRemote.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_TokenRemote *TokenRemoteCaller) TOKENREMOTESTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "TOKEN_REMOTE_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_TokenRemote *TokenRemoteSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _TokenRemote.Contract.TOKENREMOTESTORAGELOCATION(&_TokenRemote.CallOpts) +} + +// TOKENREMOTESTORAGELOCATION is a free data retrieval call binding the contract method 0x35cac159. +// +// Solidity: function TOKEN_REMOTE_STORAGE_LOCATION() view returns(bytes32) +func (_TokenRemote *TokenRemoteCallerSession) TOKENREMOTESTORAGELOCATION() ([32]byte, error) { + return _TokenRemote.Contract.TOKENREMOTESTORAGELOCATION(&_TokenRemote.CallOpts) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_TokenRemote *TokenRemoteCaller) CalculateNumWords(opts *bind.CallOpts, payloadSize *big.Int) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "calculateNumWords", payloadSize) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_TokenRemote *TokenRemoteSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _TokenRemote.Contract.CalculateNumWords(&_TokenRemote.CallOpts, payloadSize) +} + +// CalculateNumWords is a free data retrieval call binding the contract method 0xf3f981d8. +// +// Solidity: function calculateNumWords(uint256 payloadSize) pure returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) CalculateNumWords(payloadSize *big.Int) (*big.Int, error) { + return _TokenRemote.Contract.CalculateNumWords(&_TokenRemote.CallOpts, payloadSize) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_TokenRemote *TokenRemoteCaller) GetBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_TokenRemote *TokenRemoteSession) GetBlockchainID() ([32]byte, error) { + return _TokenRemote.Contract.GetBlockchainID(&_TokenRemote.CallOpts) +} + +// GetBlockchainID is a free data retrieval call binding the contract method 0x4213cf78. +// +// Solidity: function getBlockchainID() view returns(bytes32) +func (_TokenRemote *TokenRemoteCallerSession) GetBlockchainID() ([32]byte, error) { + return _TokenRemote.Contract.GetBlockchainID(&_TokenRemote.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_TokenRemote *TokenRemoteCaller) GetInitialReserveImbalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getInitialReserveImbalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_TokenRemote *TokenRemoteSession) GetInitialReserveImbalance() (*big.Int, error) { + return _TokenRemote.Contract.GetInitialReserveImbalance(&_TokenRemote.CallOpts) +} + +// GetInitialReserveImbalance is a free data retrieval call binding the contract method 0xef793e2a. +// +// Solidity: function getInitialReserveImbalance() view returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) GetInitialReserveImbalance() (*big.Int, error) { + return _TokenRemote.Contract.GetInitialReserveImbalance(&_TokenRemote.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_TokenRemote *TokenRemoteCaller) GetIsCollateralized(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getIsCollateralized") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_TokenRemote *TokenRemoteSession) GetIsCollateralized() (bool, error) { + return _TokenRemote.Contract.GetIsCollateralized(&_TokenRemote.CallOpts) +} + +// GetIsCollateralized is a free data retrieval call binding the contract method 0x02a30c7d. +// +// Solidity: function getIsCollateralized() view returns(bool) +func (_TokenRemote *TokenRemoteCallerSession) GetIsCollateralized() (bool, error) { + return _TokenRemote.Contract.GetIsCollateralized(&_TokenRemote.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TokenRemote *TokenRemoteCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TokenRemote *TokenRemoteSession) GetMinTeleporterVersion() (*big.Int, error) { + return _TokenRemote.Contract.GetMinTeleporterVersion(&_TokenRemote.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _TokenRemote.Contract.GetMinTeleporterVersion(&_TokenRemote.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_TokenRemote *TokenRemoteCaller) GetMultiplyOnRemote(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getMultiplyOnRemote") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_TokenRemote *TokenRemoteSession) GetMultiplyOnRemote() (bool, error) { + return _TokenRemote.Contract.GetMultiplyOnRemote(&_TokenRemote.CallOpts) +} + +// GetMultiplyOnRemote is a free data retrieval call binding the contract method 0x7ee3779a. +// +// Solidity: function getMultiplyOnRemote() view returns(bool) +func (_TokenRemote *TokenRemoteCallerSession) GetMultiplyOnRemote() (bool, error) { + return _TokenRemote.Contract.GetMultiplyOnRemote(&_TokenRemote.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_TokenRemote *TokenRemoteCaller) GetTokenHomeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getTokenHomeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_TokenRemote *TokenRemoteSession) GetTokenHomeAddress() (common.Address, error) { + return _TokenRemote.Contract.GetTokenHomeAddress(&_TokenRemote.CallOpts) +} + +// GetTokenHomeAddress is a free data retrieval call binding the contract method 0xc3cd6927. +// +// Solidity: function getTokenHomeAddress() view returns(address) +func (_TokenRemote *TokenRemoteCallerSession) GetTokenHomeAddress() (common.Address, error) { + return _TokenRemote.Contract.GetTokenHomeAddress(&_TokenRemote.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_TokenRemote *TokenRemoteCaller) GetTokenHomeBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getTokenHomeBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_TokenRemote *TokenRemoteSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _TokenRemote.Contract.GetTokenHomeBlockchainID(&_TokenRemote.CallOpts) +} + +// GetTokenHomeBlockchainID is a free data retrieval call binding the contract method 0xe0fd9cb8. +// +// Solidity: function getTokenHomeBlockchainID() view returns(bytes32) +func (_TokenRemote *TokenRemoteCallerSession) GetTokenHomeBlockchainID() ([32]byte, error) { + return _TokenRemote.Contract.GetTokenHomeBlockchainID(&_TokenRemote.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_TokenRemote *TokenRemoteCaller) GetTokenMultiplier(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "getTokenMultiplier") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_TokenRemote *TokenRemoteSession) GetTokenMultiplier() (*big.Int, error) { + return _TokenRemote.Contract.GetTokenMultiplier(&_TokenRemote.CallOpts) +} + +// GetTokenMultiplier is a free data retrieval call binding the contract method 0x0733c8c8. +// +// Solidity: function getTokenMultiplier() view returns(uint256) +func (_TokenRemote *TokenRemoteCallerSession) GetTokenMultiplier() (*big.Int, error) { + return _TokenRemote.Contract.GetTokenMultiplier(&_TokenRemote.CallOpts) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TokenRemote *TokenRemoteCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TokenRemote *TokenRemoteSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _TokenRemote.Contract.IsTeleporterAddressPaused(&_TokenRemote.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TokenRemote *TokenRemoteCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _TokenRemote.Contract.IsTeleporterAddressPaused(&_TokenRemote.CallOpts, teleporterAddress) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenRemote *TokenRemoteCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenRemote.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenRemote *TokenRemoteSession) Owner() (common.Address, error) { + return _TokenRemote.Contract.Owner(&_TokenRemote.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenRemote *TokenRemoteCallerSession) Owner() (common.Address, error) { + return _TokenRemote.Contract.Owner(&_TokenRemote.CallOpts) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenRemote *TokenRemoteTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenRemote.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenRemote *TokenRemoteSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenRemote.Contract.PauseTeleporterAddress(&_TokenRemote.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenRemote *TokenRemoteTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenRemote.Contract.PauseTeleporterAddress(&_TokenRemote.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TokenRemote *TokenRemoteTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TokenRemote.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TokenRemote *TokenRemoteSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TokenRemote.Contract.ReceiveTeleporterMessage(&_TokenRemote.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TokenRemote *TokenRemoteTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TokenRemote.Contract.ReceiveTeleporterMessage(&_TokenRemote.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_TokenRemote *TokenRemoteTransactor) RegisterWithHome(opts *bind.TransactOpts, feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _TokenRemote.contract.Transact(opts, "registerWithHome", feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_TokenRemote *TokenRemoteSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _TokenRemote.Contract.RegisterWithHome(&_TokenRemote.TransactOpts, feeInfo) +} + +// RegisterWithHome is a paid mutator transaction binding the contract method 0xb8a46d02. +// +// Solidity: function registerWithHome((address,uint256) feeInfo) returns() +func (_TokenRemote *TokenRemoteTransactorSession) RegisterWithHome(feeInfo TeleporterFeeInfo) (*types.Transaction, error) { + return _TokenRemote.Contract.RegisterWithHome(&_TokenRemote.TransactOpts, feeInfo) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TokenRemote *TokenRemoteTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenRemote.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TokenRemote *TokenRemoteSession) RenounceOwnership() (*types.Transaction, error) { + return _TokenRemote.Contract.RenounceOwnership(&_TokenRemote.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TokenRemote *TokenRemoteTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _TokenRemote.Contract.RenounceOwnership(&_TokenRemote.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenRemote *TokenRemoteTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TokenRemote.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenRemote *TokenRemoteSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TokenRemote.Contract.TransferOwnership(&_TokenRemote.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenRemote *TokenRemoteTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TokenRemote.Contract.TransferOwnership(&_TokenRemote.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenRemote *TokenRemoteTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenRemote.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenRemote *TokenRemoteSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenRemote.Contract.UnpauseTeleporterAddress(&_TokenRemote.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TokenRemote *TokenRemoteTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TokenRemote.Contract.UnpauseTeleporterAddress(&_TokenRemote.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TokenRemote *TokenRemoteTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _TokenRemote.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TokenRemote *TokenRemoteSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _TokenRemote.Contract.UpdateMinTeleporterVersion(&_TokenRemote.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TokenRemote *TokenRemoteTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _TokenRemote.Contract.UpdateMinTeleporterVersion(&_TokenRemote.TransactOpts, version) +} + +// TokenRemoteCallFailedIterator is returned from FilterCallFailed and is used to iterate over the raw logs and unpacked data for CallFailed events raised by the TokenRemote contract. +type TokenRemoteCallFailedIterator struct { + Event *TokenRemoteCallFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteCallFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteCallFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteCallFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteCallFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteCallFailed represents a CallFailed event raised by the TokenRemote contract. +type TokenRemoteCallFailed struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallFailed is a free log retrieval operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) FilterCallFailed(opts *bind.FilterOpts, recipientContract []common.Address) (*TokenRemoteCallFailedIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return &TokenRemoteCallFailedIterator{contract: _TokenRemote.contract, event: "CallFailed", logs: logs, sub: sub}, nil +} + +// WatchCallFailed is a free log subscription operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) WatchCallFailed(opts *bind.WatchOpts, sink chan<- *TokenRemoteCallFailed, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "CallFailed", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteCallFailed) + if err := _TokenRemote.contract.UnpackLog(event, "CallFailed", 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 +} + +// ParseCallFailed is a log parse operation binding the contract event 0xb9eaeae386d339f8115782f297a9e5f0e13fb587cd6b0d502f113cb8dd4d6cb0. +// +// Solidity: event CallFailed(address indexed recipientContract, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) ParseCallFailed(log types.Log) (*TokenRemoteCallFailed, error) { + event := new(TokenRemoteCallFailed) + if err := _TokenRemote.contract.UnpackLog(event, "CallFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteCallSucceededIterator is returned from FilterCallSucceeded and is used to iterate over the raw logs and unpacked data for CallSucceeded events raised by the TokenRemote contract. +type TokenRemoteCallSucceededIterator struct { + Event *TokenRemoteCallSucceeded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteCallSucceededIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteCallSucceeded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteCallSucceededIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteCallSucceededIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteCallSucceeded represents a CallSucceeded event raised by the TokenRemote contract. +type TokenRemoteCallSucceeded struct { + RecipientContract common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCallSucceeded is a free log retrieval operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) FilterCallSucceeded(opts *bind.FilterOpts, recipientContract []common.Address) (*TokenRemoteCallSucceededIterator, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return &TokenRemoteCallSucceededIterator{contract: _TokenRemote.contract, event: "CallSucceeded", logs: logs, sub: sub}, nil +} + +// WatchCallSucceeded is a free log subscription operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) WatchCallSucceeded(opts *bind.WatchOpts, sink chan<- *TokenRemoteCallSucceeded, recipientContract []common.Address) (event.Subscription, error) { + + var recipientContractRule []interface{} + for _, recipientContractItem := range recipientContract { + recipientContractRule = append(recipientContractRule, recipientContractItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "CallSucceeded", recipientContractRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteCallSucceeded) + if err := _TokenRemote.contract.UnpackLog(event, "CallSucceeded", 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 +} + +// ParseCallSucceeded is a log parse operation binding the contract event 0x104deb555f67e63782bb817bc26c39050894645f9b9f29c4be8ae68d0e8b7ff4. +// +// Solidity: event CallSucceeded(address indexed recipientContract, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) ParseCallSucceeded(log types.Log) (*TokenRemoteCallSucceeded, error) { + event := new(TokenRemoteCallSucceeded) + if err := _TokenRemote.contract.UnpackLog(event, "CallSucceeded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TokenRemote contract. +type TokenRemoteInitializedIterator struct { + Event *TokenRemoteInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteInitialized represents a Initialized event raised by the TokenRemote contract. +type TokenRemoteInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TokenRemote *TokenRemoteFilterer) FilterInitialized(opts *bind.FilterOpts) (*TokenRemoteInitializedIterator, error) { + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TokenRemoteInitializedIterator{contract: _TokenRemote.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TokenRemote *TokenRemoteFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TokenRemoteInitialized) (event.Subscription, error) { + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteInitialized) + if err := _TokenRemote.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TokenRemote *TokenRemoteFilterer) ParseInitialized(log types.Log) (*TokenRemoteInitialized, error) { + event := new(TokenRemoteInitialized) + if err := _TokenRemote.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the TokenRemote contract. +type TokenRemoteMinTeleporterVersionUpdatedIterator struct { + Event *TokenRemoteMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the TokenRemote contract. +type TokenRemoteMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TokenRemote *TokenRemoteFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*TokenRemoteMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &TokenRemoteMinTeleporterVersionUpdatedIterator{contract: _TokenRemote.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TokenRemote *TokenRemoteFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *TokenRemoteMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteMinTeleporterVersionUpdated) + if err := _TokenRemote.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TokenRemote *TokenRemoteFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*TokenRemoteMinTeleporterVersionUpdated, error) { + event := new(TokenRemoteMinTeleporterVersionUpdated) + if err := _TokenRemote.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TokenRemote contract. +type TokenRemoteOwnershipTransferredIterator struct { + Event *TokenRemoteOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteOwnershipTransferred represents a OwnershipTransferred event raised by the TokenRemote contract. +type TokenRemoteOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenRemote *TokenRemoteFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TokenRemoteOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TokenRemoteOwnershipTransferredIterator{contract: _TokenRemote.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenRemote *TokenRemoteFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenRemoteOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteOwnershipTransferred) + if err := _TokenRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenRemote *TokenRemoteFilterer) ParseOwnershipTransferred(log types.Log) (*TokenRemoteOwnershipTransferred, error) { + event := new(TokenRemoteOwnershipTransferred) + if err := _TokenRemote.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the TokenRemote contract. +type TokenRemoteTeleporterAddressPausedIterator struct { + Event *TokenRemoteTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the TokenRemote contract. +type TokenRemoteTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TokenRemote *TokenRemoteFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*TokenRemoteTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &TokenRemoteTeleporterAddressPausedIterator{contract: _TokenRemote.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TokenRemote *TokenRemoteFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *TokenRemoteTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteTeleporterAddressPaused) + if err := _TokenRemote.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TokenRemote *TokenRemoteFilterer) ParseTeleporterAddressPaused(log types.Log) (*TokenRemoteTeleporterAddressPaused, error) { + event := new(TokenRemoteTeleporterAddressPaused) + if err := _TokenRemote.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the TokenRemote contract. +type TokenRemoteTeleporterAddressUnpausedIterator struct { + Event *TokenRemoteTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the TokenRemote contract. +type TokenRemoteTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TokenRemote *TokenRemoteFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*TokenRemoteTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &TokenRemoteTeleporterAddressUnpausedIterator{contract: _TokenRemote.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TokenRemote *TokenRemoteFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *TokenRemoteTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteTeleporterAddressUnpaused) + if err := _TokenRemote.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TokenRemote *TokenRemoteFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*TokenRemoteTeleporterAddressUnpaused, error) { + event := new(TokenRemoteTeleporterAddressUnpaused) + if err := _TokenRemote.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteTokensAndCallSentIterator is returned from FilterTokensAndCallSent and is used to iterate over the raw logs and unpacked data for TokensAndCallSent events raised by the TokenRemote contract. +type TokenRemoteTokensAndCallSentIterator struct { + Event *TokenRemoteTokensAndCallSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteTokensAndCallSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTokensAndCallSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteTokensAndCallSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteTokensAndCallSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteTokensAndCallSent represents a TokensAndCallSent event raised by the TokenRemote contract. +type TokenRemoteTokensAndCallSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendAndCallInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensAndCallSent is a free log retrieval operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) FilterTokensAndCallSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*TokenRemoteTokensAndCallSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &TokenRemoteTokensAndCallSentIterator{contract: _TokenRemote.contract, event: "TokensAndCallSent", logs: logs, sub: sub}, nil +} + +// WatchTokensAndCallSent is a free log subscription operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) WatchTokensAndCallSent(opts *bind.WatchOpts, sink chan<- *TokenRemoteTokensAndCallSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "TokensAndCallSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteTokensAndCallSent) + if err := _TokenRemote.contract.UnpackLog(event, "TokensAndCallSent", 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 +} + +// ParseTokensAndCallSent is a log parse operation binding the contract event 0x5d76dff81bf773b908b050fa113d39f7d8135bb4175398f313ea19cd3a1a0b16. +// +// Solidity: event TokensAndCallSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,bytes,uint256,uint256,address,address,address,uint256,uint256) input, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) ParseTokensAndCallSent(log types.Log) (*TokenRemoteTokensAndCallSent, error) { + event := new(TokenRemoteTokensAndCallSent) + if err := _TokenRemote.contract.UnpackLog(event, "TokensAndCallSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteTokensSentIterator is returned from FilterTokensSent and is used to iterate over the raw logs and unpacked data for TokensSent events raised by the TokenRemote contract. +type TokenRemoteTokensSentIterator struct { + Event *TokenRemoteTokensSent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteTokensSentIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTokensSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteTokensSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteTokensSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteTokensSent represents a TokensSent event raised by the TokenRemote contract. +type TokenRemoteTokensSent struct { + TeleporterMessageID [32]byte + Sender common.Address + Input SendTokensInput + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensSent is a free log retrieval operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) FilterTokensSent(opts *bind.FilterOpts, teleporterMessageID [][32]byte, sender []common.Address) (*TokenRemoteTokensSentIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return &TokenRemoteTokensSentIterator{contract: _TokenRemote.contract, event: "TokensSent", logs: logs, sub: sub}, nil +} + +// WatchTokensSent is a free log subscription operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) WatchTokensSent(opts *bind.WatchOpts, sink chan<- *TokenRemoteTokensSent, teleporterMessageID [][32]byte, sender []common.Address) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "TokensSent", teleporterMessageIDRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteTokensSent) + if err := _TokenRemote.contract.UnpackLog(event, "TokensSent", 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 +} + +// ParseTokensSent is a log parse operation binding the contract event 0x93f19bf1ec58a15dc643b37e7e18a1c13e85e06cd11929e283154691ace9fb52. +// +// Solidity: event TokensSent(bytes32 indexed teleporterMessageID, address indexed sender, (bytes32,address,address,address,uint256,uint256,uint256,address) input, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) ParseTokensSent(log types.Log) (*TokenRemoteTokensSent, error) { + event := new(TokenRemoteTokensSent) + if err := _TokenRemote.contract.UnpackLog(event, "TokensSent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenRemoteTokensWithdrawnIterator is returned from FilterTokensWithdrawn and is used to iterate over the raw logs and unpacked data for TokensWithdrawn events raised by the TokenRemote contract. +type TokenRemoteTokensWithdrawnIterator struct { + Event *TokenRemoteTokensWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenRemoteTokensWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenRemoteTokensWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenRemoteTokensWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenRemoteTokensWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenRemoteTokensWithdrawn represents a TokensWithdrawn event raised by the TokenRemote contract. +type TokenRemoteTokensWithdrawn struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensWithdrawn is a free log retrieval operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) FilterTokensWithdrawn(opts *bind.FilterOpts, recipient []common.Address) (*TokenRemoteTokensWithdrawnIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenRemote.contract.FilterLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return &TokenRemoteTokensWithdrawnIterator{contract: _TokenRemote.contract, event: "TokensWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchTokensWithdrawn is a free log subscription operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) WatchTokensWithdrawn(opts *bind.WatchOpts, sink chan<- *TokenRemoteTokensWithdrawn, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _TokenRemote.contract.WatchLogs(opts, "TokensWithdrawn", recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenRemoteTokensWithdrawn) + if err := _TokenRemote.contract.UnpackLog(event, "TokensWithdrawn", 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 +} + +// ParseTokensWithdrawn is a log parse operation binding the contract event 0x6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b. +// +// Solidity: event TokensWithdrawn(address indexed recipient, uint256 amount) +func (_TokenRemote *TokenRemoteFilterer) ParseTokensWithdrawn(log types.Log) (*TokenRemoteTokensWithdrawn, error) { + event := new(TokenRemoteTokensWithdrawn) + if err := _TokenRemote.contract.UnpackLog(event, "TokensWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/WrappedNativeToken/WrappedNativeToken.go b/abi-bindings/go/ictt/WrappedNativeToken/WrappedNativeToken.go new file mode 100644 index 000000000..bee337584 --- /dev/null +++ b/abi-bindings/go/ictt/WrappedNativeToken/WrappedNativeToken.go @@ -0,0 +1,1134 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package wrappednativetoken + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// WrappedNativeTokenMetaData contains all meta data concerning the WrappedNativeToken contract. +var WrappedNativeTokenMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x608060405234801561000f575f80fd5b50604051610c5e380380610c5e83398101604081905261002e916100c7565b8060405160200161003f919061016e565b6040516020818303038152906040528160405160200161005f919061019d565b60408051601f19818403018152919052600361007b8382610249565b5060046100888282610249565b50505050610308565b634e487b7160e01b5f52604160045260245ffd5b5f5b838110156100bf5781810151838201526020016100a7565b50505f910152565b5f602082840312156100d7575f80fd5b81516001600160401b03808211156100ed575f80fd5b818401915084601f830112610100575f80fd5b81518181111561011257610112610091565b604051601f8201601f19908116603f0116810190838211818310171561013a5761013a610091565b81604052828152876020848701011115610152575f80fd5b6101638360208301602088016100a5565b979650505050505050565b6702bb930b83832b2160c51b81525f82516101908160088501602087016100a5565b9190910160080192915050565b605760f81b81525f82516101b88160018501602087016100a5565b9190910160010192915050565b600181811c908216806101d957607f821691505b6020821081036101f757634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561024457805f5260205f20601f840160051c810160208510156102225750805b601f840160051c820191505b81811015610241575f815560010161022e565b50505b505050565b81516001600160401b0381111561026257610262610091565b6102768161027084546101c5565b846101fd565b602080601f8311600181146102a9575f84156102925750858301515b5f19600386901b1c1916600185901b178555610300565b5f85815260208120601f198616915b828110156102d7578886015182559484019460019091019084016102b8565b50858210156102f457878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b610949806103155f395ff3fe60806040526004361061009f575f3560e01c8063313ce56711610063578063313ce5671461016b57806370a082311461018657806395d89b41146101ba578063a9059cbb146101ce578063d0e30db0146100ae578063dd62ed3e146101ed576100ae565b806306fdde03146100b6578063095ea7b3146100e057806318160ddd1461010f57806323b872dd1461012d5780632e1a7d4d1461014c576100ae565b366100ae576100ac610231565b005b6100ac610231565b3480156100c1575f80fd5b506100ca610272565b6040516100d7919061078c565b60405180910390f35b3480156100eb575f80fd5b506100ff6100fa3660046107f3565b610302565b60405190151581526020016100d7565b34801561011a575f80fd5b506002545b6040519081526020016100d7565b348015610138575f80fd5b506100ff61014736600461081b565b61031b565b348015610157575f80fd5b506100ac610166366004610854565b61033e565b348015610176575f80fd5b50604051601281526020016100d7565b348015610191575f80fd5b5061011f6101a036600461086b565b6001600160a01b03165f9081526020819052604090205490565b3480156101c5575f80fd5b506100ca61038a565b3480156101d9575f80fd5b506100ff6101e83660046107f3565b610399565b3480156101f8575f80fd5b5061011f61020736600461088b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b61023b33346103a6565b60405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b606060038054610281906108bc565b80601f01602080910402602001604051908101604052809291908181526020018280546102ad906108bc565b80156102f85780601f106102cf576101008083540402835291602001916102f8565b820191905f5260205f20905b8154815290600101906020018083116102db57829003601f168201915b5050505050905090565b5f3361030f8185856103e3565b60019150505b92915050565b5f336103288582856103f5565b610333858585610470565b506001949350505050565b61034833826104cd565b60405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a26103873382610501565b50565b606060048054610281906108bc565b5f3361030f818585610470565b6001600160a01b0382166103d45760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6103df5f8383610594565b5050565b6103f083838360016106ba565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811461046a578181101561045c57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016103cb565b61046a84848484035f6106ba565b50505050565b6001600160a01b03831661049957604051634b637e8f60e11b81525f60048201526024016103cb565b6001600160a01b0382166104c25760405163ec442f0560e01b81525f60048201526024016103cb565b6103f0838383610594565b6001600160a01b0382166104f657604051634b637e8f60e11b81525f60048201526024016103cb565b6103df825f83610594565b804710156105245760405163cd78605960e01b81523060048201526024016103cb565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f811461056d576040519150601f19603f3d011682016040523d82523d5f602084013e610572565b606091505b50509050806103f057604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0383166105be578060025f8282546105b391906108f4565b9091555061062e9050565b6001600160a01b0383165f90815260208190526040902054818110156106105760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016103cb565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661064a57600280548290039055610668565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516106ad91815260200190565b60405180910390a3505050565b6001600160a01b0384166106e35760405163e602df0560e01b81525f60048201526024016103cb565b6001600160a01b03831661070c57604051634a1406b160e11b81525f60048201526024016103cb565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561046a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161077e91815260200190565b60405180910390a350505050565b5f602080835283518060208501525f5b818110156107b85785810183015185820160400152820161079c565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107ee575f80fd5b919050565b5f8060408385031215610804575f80fd5b61080d836107d8565b946020939093013593505050565b5f805f6060848603121561082d575f80fd5b610836846107d8565b9250610844602085016107d8565b9150604084013590509250925092565b5f60208284031215610864575f80fd5b5035919050565b5f6020828403121561087b575f80fd5b610884826107d8565b9392505050565b5f806040838503121561089c575f80fd5b6108a5836107d8565b91506108b3602084016107d8565b90509250929050565b600181811c908216806108d057607f821691505b6020821081036108ee57634e487b7160e01b5f52602260045260245ffd5b50919050565b8082018082111561031557634e487b7160e01b5f52601160045260245ffdfea26469706673582212204b5fefaca6ac6ea34d19cc500e0cc0c91872dae528222cf448f2b491272fa84b64736f6c63430008190033", +} + +// WrappedNativeTokenABI is the input ABI used to generate the binding from. +// Deprecated: Use WrappedNativeTokenMetaData.ABI instead. +var WrappedNativeTokenABI = WrappedNativeTokenMetaData.ABI + +// WrappedNativeTokenBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use WrappedNativeTokenMetaData.Bin instead. +var WrappedNativeTokenBin = WrappedNativeTokenMetaData.Bin + +// DeployWrappedNativeToken deploys a new Ethereum contract, binding an instance of WrappedNativeToken to it. +func DeployWrappedNativeToken(auth *bind.TransactOpts, backend bind.ContractBackend, symbol string) (common.Address, *types.Transaction, *WrappedNativeToken, error) { + parsed, err := WrappedNativeTokenMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(WrappedNativeTokenBin), backend, symbol) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &WrappedNativeToken{WrappedNativeTokenCaller: WrappedNativeTokenCaller{contract: contract}, WrappedNativeTokenTransactor: WrappedNativeTokenTransactor{contract: contract}, WrappedNativeTokenFilterer: WrappedNativeTokenFilterer{contract: contract}}, nil +} + +// WrappedNativeToken is an auto generated Go binding around an Ethereum contract. +type WrappedNativeToken struct { + WrappedNativeTokenCaller // Read-only binding to the contract + WrappedNativeTokenTransactor // Write-only binding to the contract + WrappedNativeTokenFilterer // Log filterer for contract events +} + +// WrappedNativeTokenCaller is an auto generated read-only Go binding around an Ethereum contract. +type WrappedNativeTokenCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// WrappedNativeTokenTransactor is an auto generated write-only Go binding around an Ethereum contract. +type WrappedNativeTokenTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// WrappedNativeTokenFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type WrappedNativeTokenFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// WrappedNativeTokenSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type WrappedNativeTokenSession struct { + Contract *WrappedNativeToken // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// WrappedNativeTokenCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type WrappedNativeTokenCallerSession struct { + Contract *WrappedNativeTokenCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// WrappedNativeTokenTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type WrappedNativeTokenTransactorSession struct { + Contract *WrappedNativeTokenTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// WrappedNativeTokenRaw is an auto generated low-level Go binding around an Ethereum contract. +type WrappedNativeTokenRaw struct { + Contract *WrappedNativeToken // Generic contract binding to access the raw methods on +} + +// WrappedNativeTokenCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type WrappedNativeTokenCallerRaw struct { + Contract *WrappedNativeTokenCaller // Generic read-only contract binding to access the raw methods on +} + +// WrappedNativeTokenTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type WrappedNativeTokenTransactorRaw struct { + Contract *WrappedNativeTokenTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewWrappedNativeToken creates a new instance of WrappedNativeToken, bound to a specific deployed contract. +func NewWrappedNativeToken(address common.Address, backend bind.ContractBackend) (*WrappedNativeToken, error) { + contract, err := bindWrappedNativeToken(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &WrappedNativeToken{WrappedNativeTokenCaller: WrappedNativeTokenCaller{contract: contract}, WrappedNativeTokenTransactor: WrappedNativeTokenTransactor{contract: contract}, WrappedNativeTokenFilterer: WrappedNativeTokenFilterer{contract: contract}}, nil +} + +// NewWrappedNativeTokenCaller creates a new read-only instance of WrappedNativeToken, bound to a specific deployed contract. +func NewWrappedNativeTokenCaller(address common.Address, caller bind.ContractCaller) (*WrappedNativeTokenCaller, error) { + contract, err := bindWrappedNativeToken(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &WrappedNativeTokenCaller{contract: contract}, nil +} + +// NewWrappedNativeTokenTransactor creates a new write-only instance of WrappedNativeToken, bound to a specific deployed contract. +func NewWrappedNativeTokenTransactor(address common.Address, transactor bind.ContractTransactor) (*WrappedNativeTokenTransactor, error) { + contract, err := bindWrappedNativeToken(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &WrappedNativeTokenTransactor{contract: contract}, nil +} + +// NewWrappedNativeTokenFilterer creates a new log filterer instance of WrappedNativeToken, bound to a specific deployed contract. +func NewWrappedNativeTokenFilterer(address common.Address, filterer bind.ContractFilterer) (*WrappedNativeTokenFilterer, error) { + contract, err := bindWrappedNativeToken(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &WrappedNativeTokenFilterer{contract: contract}, nil +} + +// bindWrappedNativeToken binds a generic wrapper to an already deployed contract. +func bindWrappedNativeToken(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := WrappedNativeTokenMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_WrappedNativeToken *WrappedNativeTokenRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WrappedNativeToken.Contract.WrappedNativeTokenCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_WrappedNativeToken *WrappedNativeTokenRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.WrappedNativeTokenTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_WrappedNativeToken *WrappedNativeTokenRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.WrappedNativeTokenTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_WrappedNativeToken *WrappedNativeTokenCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WrappedNativeToken.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_WrappedNativeToken *WrappedNativeTokenTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_WrappedNativeToken *WrappedNativeTokenTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _WrappedNativeToken.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _WrappedNativeToken.Contract.Allowance(&_WrappedNativeToken.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _WrappedNativeToken.Contract.Allowance(&_WrappedNativeToken.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _WrappedNativeToken.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenSession) BalanceOf(account common.Address) (*big.Int, error) { + return _WrappedNativeToken.Contract.BalanceOf(&_WrappedNativeToken.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _WrappedNativeToken.Contract.BalanceOf(&_WrappedNativeToken.CallOpts, account) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_WrappedNativeToken *WrappedNativeTokenCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _WrappedNativeToken.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_WrappedNativeToken *WrappedNativeTokenSession) Decimals() (uint8, error) { + return _WrappedNativeToken.Contract.Decimals(&_WrappedNativeToken.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_WrappedNativeToken *WrappedNativeTokenCallerSession) Decimals() (uint8, error) { + return _WrappedNativeToken.Contract.Decimals(&_WrappedNativeToken.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_WrappedNativeToken *WrappedNativeTokenCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WrappedNativeToken.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_WrappedNativeToken *WrappedNativeTokenSession) Name() (string, error) { + return _WrappedNativeToken.Contract.Name(&_WrappedNativeToken.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_WrappedNativeToken *WrappedNativeTokenCallerSession) Name() (string, error) { + return _WrappedNativeToken.Contract.Name(&_WrappedNativeToken.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_WrappedNativeToken *WrappedNativeTokenCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WrappedNativeToken.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_WrappedNativeToken *WrappedNativeTokenSession) Symbol() (string, error) { + return _WrappedNativeToken.Contract.Symbol(&_WrappedNativeToken.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_WrappedNativeToken *WrappedNativeTokenCallerSession) Symbol() (string, error) { + return _WrappedNativeToken.Contract.Symbol(&_WrappedNativeToken.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _WrappedNativeToken.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenSession) TotalSupply() (*big.Int, error) { + return _WrappedNativeToken.Contract.TotalSupply(&_WrappedNativeToken.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_WrappedNativeToken *WrappedNativeTokenCallerSession) TotalSupply() (*big.Int, error) { + return _WrappedNativeToken.Contract.TotalSupply(&_WrappedNativeToken.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Approve(&_WrappedNativeToken.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Approve(&_WrappedNativeToken.TransactOpts, spender, value) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WrappedNativeToken.contract.Transact(opts, "deposit") +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenSession) Deposit() (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Deposit(&_WrappedNativeToken.TransactOpts) +} + +// Deposit is a paid mutator transaction binding the contract method 0xd0e30db0. +// +// Solidity: function deposit() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactorSession) Deposit() (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Deposit(&_WrappedNativeToken.TransactOpts) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Transfer(&_WrappedNativeToken.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Transfer(&_WrappedNativeToken.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.TransferFrom(&_WrappedNativeToken.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_WrappedNativeToken *WrappedNativeTokenTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.TransferFrom(&_WrappedNativeToken.TransactOpts, from, to, value) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactor) Withdraw(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.contract.Transact(opts, "withdraw", amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_WrappedNativeToken *WrappedNativeTokenSession) Withdraw(amount *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Withdraw(&_WrappedNativeToken.TransactOpts, amount) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x2e1a7d4d. +// +// Solidity: function withdraw(uint256 amount) returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactorSession) Withdraw(amount *big.Int) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Withdraw(&_WrappedNativeToken.TransactOpts, amount) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _WrappedNativeToken.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Fallback(&_WrappedNativeToken.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Fallback(&_WrappedNativeToken.TransactOpts, calldata) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WrappedNativeToken.contract.RawTransact(opts, nil) // calldata is disallowed for receive function +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenSession) Receive() (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Receive(&_WrappedNativeToken.TransactOpts) +} + +// Receive is a paid mutator transaction binding the contract receive function. +// +// Solidity: receive() payable returns() +func (_WrappedNativeToken *WrappedNativeTokenTransactorSession) Receive() (*types.Transaction, error) { + return _WrappedNativeToken.Contract.Receive(&_WrappedNativeToken.TransactOpts) +} + +// WrappedNativeTokenApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the WrappedNativeToken contract. +type WrappedNativeTokenApprovalIterator struct { + Event *WrappedNativeTokenApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *WrappedNativeTokenApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *WrappedNativeTokenApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *WrappedNativeTokenApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// WrappedNativeTokenApproval represents a Approval event raised by the WrappedNativeToken contract. +type WrappedNativeTokenApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*WrappedNativeTokenApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _WrappedNativeToken.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &WrappedNativeTokenApprovalIterator{contract: _WrappedNativeToken.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *WrappedNativeTokenApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _WrappedNativeToken.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(WrappedNativeTokenApproval) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) ParseApproval(log types.Log) (*WrappedNativeTokenApproval, error) { + event := new(WrappedNativeTokenApproval) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// WrappedNativeTokenDepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the WrappedNativeToken contract. +type WrappedNativeTokenDepositIterator struct { + Event *WrappedNativeTokenDeposit // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *WrappedNativeTokenDepositIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *WrappedNativeTokenDepositIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *WrappedNativeTokenDepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// WrappedNativeTokenDeposit represents a Deposit event raised by the WrappedNativeToken contract. +type WrappedNativeTokenDeposit struct { + Sender common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDeposit is a free log retrieval operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) FilterDeposit(opts *bind.FilterOpts, sender []common.Address) (*WrappedNativeTokenDepositIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _WrappedNativeToken.contract.FilterLogs(opts, "Deposit", senderRule) + if err != nil { + return nil, err + } + return &WrappedNativeTokenDepositIterator{contract: _WrappedNativeToken.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +// WatchDeposit is a free log subscription operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *WrappedNativeTokenDeposit, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _WrappedNativeToken.contract.WatchLogs(opts, "Deposit", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(WrappedNativeTokenDeposit) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDeposit is a log parse operation binding the contract event 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c. +// +// Solidity: event Deposit(address indexed sender, uint256 amount) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) ParseDeposit(log types.Log) (*WrappedNativeTokenDeposit, error) { + event := new(WrappedNativeTokenDeposit) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// WrappedNativeTokenTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the WrappedNativeToken contract. +type WrappedNativeTokenTransferIterator struct { + Event *WrappedNativeTokenTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *WrappedNativeTokenTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *WrappedNativeTokenTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *WrappedNativeTokenTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// WrappedNativeTokenTransfer represents a Transfer event raised by the WrappedNativeToken contract. +type WrappedNativeTokenTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*WrappedNativeTokenTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _WrappedNativeToken.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &WrappedNativeTokenTransferIterator{contract: _WrappedNativeToken.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *WrappedNativeTokenTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _WrappedNativeToken.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(WrappedNativeTokenTransfer) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) ParseTransfer(log types.Log) (*WrappedNativeTokenTransfer, error) { + event := new(WrappedNativeTokenTransfer) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// WrappedNativeTokenWithdrawalIterator is returned from FilterWithdrawal and is used to iterate over the raw logs and unpacked data for Withdrawal events raised by the WrappedNativeToken contract. +type WrappedNativeTokenWithdrawalIterator struct { + Event *WrappedNativeTokenWithdrawal // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *WrappedNativeTokenWithdrawalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(WrappedNativeTokenWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *WrappedNativeTokenWithdrawalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *WrappedNativeTokenWithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// WrappedNativeTokenWithdrawal represents a Withdrawal event raised by the WrappedNativeToken contract. +type WrappedNativeTokenWithdrawal struct { + Sender common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawal is a free log retrieval operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) FilterWithdrawal(opts *bind.FilterOpts, sender []common.Address) (*WrappedNativeTokenWithdrawalIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _WrappedNativeToken.contract.FilterLogs(opts, "Withdrawal", senderRule) + if err != nil { + return nil, err + } + return &WrappedNativeTokenWithdrawalIterator{contract: _WrappedNativeToken.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +// WatchWithdrawal is a free log subscription operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *WrappedNativeTokenWithdrawal, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _WrappedNativeToken.contract.WatchLogs(opts, "Withdrawal", senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(WrappedNativeTokenWithdrawal) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseWithdrawal is a log parse operation binding the contract event 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65. +// +// Solidity: event Withdrawal(address indexed sender, uint256 amount) +func (_WrappedNativeToken *WrappedNativeTokenFilterer) ParseWithdrawal(log types.Log) (*WrappedNativeTokenWithdrawal, error) { + event := new(WrappedNativeTokenWithdrawal) + if err := _WrappedNativeToken.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/mocks/ExampleERC20Decimals/ExampleERC20Decimals.go b/abi-bindings/go/ictt/mocks/ExampleERC20Decimals/ExampleERC20Decimals.go new file mode 100644 index 000000000..49cb345fa --- /dev/null +++ b/abi-bindings/go/ictt/mocks/ExampleERC20Decimals/ExampleERC20Decimals.go @@ -0,0 +1,875 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package exampleerc20decimals + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ExampleERC20DecimalsMetaData contains all meta data concerning the ExampleERC20Decimals contract. +var ExampleERC20DecimalsMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"tokenDecimals_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561000f575f80fd5b50604051610d2a380380610d2a83398101604081905261002e91610217565b6040518060400160405280600a81526020016926b7b1b5902a37b5b2b760b11b81525060405180604001604052806004815260200163045584d560e41b815250816003908161007d91906102d6565b50600461008a82826102d6565b5050506100a9336b204fce5e3e250261100000006100b460201b60201c565b60ff166080526103ba565b6001600160a01b0382166100e25760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100ed5f83836100f1565b5050565b6001600160a01b03831661011b578060025f8282546101109190610395565b9091555061018b9050565b6001600160a01b0383165f908152602081905260409020548181101561016d5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016100d9565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166101a7576002805482900390556101c5565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161020a91815260200190565b60405180910390a3505050565b5f60208284031215610227575f80fd5b815160ff81168114610237575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061026657607f821691505b60208210810361028457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156102d157805f5260205f20601f840160051c810160208510156102af5750805b601f840160051c820191505b818110156102ce575f81556001016102bb565b50505b505050565b81516001600160401b038111156102ef576102ef61023e565b610303816102fd8454610252565b8461028a565b602080601f831160018114610336575f841561031f5750858301515b5f19600386901b1c1916600185901b17855561038d565b5f85815260208120601f198616915b8281101561036457888601518255948401946001909101908401610345565b508582101561038157878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b808201808211156103b457634e487b7160e01b5f52601160045260245ffd5b92915050565b6080516109516103d95f395f8181610151015261018801526109515ff3fe608060405234801561000f575f80fd5b50600436106100e5575f3560e01c806342966c681161008857806395d89b411161006357806395d89b411461020d578063a0712d6814610215578063a9059cbb14610228578063dd62ed3e1461023b575f80fd5b806342966c68146101bf57806370a08231146101d257806379cc6790146101fa575f80fd5b806323b872dd116100c357806323b872dd1461013c578063313ce5671461014f5780633b97e8561461018357806340c10f19146101aa575f80fd5b806306fdde03146100e9578063095ea7b31461010757806318160ddd1461012a575b5f80fd5b6100f1610273565b6040516100fe9190610794565b60405180910390f35b61011a6101153660046107fb565b610303565b60405190151581526020016100fe565b6002545b6040519081526020016100fe565b61011a61014a366004610823565b61031c565b7f00000000000000000000000000000000000000000000000000000000000000005b60405160ff90911681526020016100fe565b6101717f000000000000000000000000000000000000000000000000000000000000000081565b6101bd6101b83660046107fb565b61033f565b005b6101bd6101cd36600461085c565b6103aa565b61012e6101e0366004610873565b6001600160a01b03165f9081526020819052604090205490565b6101bd6102083660046107fb565b6103b7565b6100f16103cc565b6101bd61022336600461085c565b6103db565b61011a6102363660046107fb565b61043d565b61012e610249366004610893565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b606060038054610282906108c4565b80601f01602080910402602001604051908101604052809291908181526020018280546102ae906108c4565b80156102f95780601f106102d0576101008083540402835291602001916102f9565b820191905f5260205f20905b8154815290600101906020018083116102dc57829003601f168201915b5050505050905090565b5f3361031081858561044a565b60019150505b92915050565b5f3361032985828561045c565b6103348585856104d7565b506001949350505050565b678ac7230489e8000081111561039c5760405162461bcd60e51b815260206004820152601f60248201527f4578616d706c6545524332303a206d6178206d696e742065786365656465640060448201526064015b60405180910390fd5b6103a68282610534565b5050565b6103b43382610568565b50565b6103c282338361045c565b6103a68282610568565b606060048054610282906108c4565b678ac7230489e800008111156104335760405162461bcd60e51b815260206004820152601f60248201527f4578616d706c6545524332303a206d6178206d696e74206578636565646564006044820152606401610393565b6103b43382610534565b5f336103108185856104d7565b610457838383600161059c565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146104d157818110156104c357604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610393565b6104d184848484035f61059c565b50505050565b6001600160a01b03831661050057604051634b637e8f60e11b81525f6004820152602401610393565b6001600160a01b0382166105295760405163ec442f0560e01b81525f6004820152602401610393565b61045783838361066e565b6001600160a01b03821661055d5760405163ec442f0560e01b81525f6004820152602401610393565b6103a65f838361066e565b6001600160a01b03821661059157604051634b637e8f60e11b81525f6004820152602401610393565b6103a6825f8361066e565b6001600160a01b0384166105c55760405163e602df0560e01b81525f6004820152602401610393565b6001600160a01b0383166105ee57604051634a1406b160e11b81525f6004820152602401610393565b6001600160a01b038085165f90815260016020908152604080832093871683529290522082905580156104d157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161066091815260200190565b60405180910390a350505050565b6001600160a01b038316610698578060025f82825461068d91906108fc565b909155506107089050565b6001600160a01b0383165f90815260208190526040902054818110156106ea5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610393565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661072457600280548290039055610742565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161078791815260200190565b60405180910390a3505050565b5f602080835283518060208501525f5b818110156107c0578581018301518582016040015282016107a4565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107f6575f80fd5b919050565b5f806040838503121561080c575f80fd5b610815836107e0565b946020939093013593505050565b5f805f60608486031215610835575f80fd5b61083e846107e0565b925061084c602085016107e0565b9150604084013590509250925092565b5f6020828403121561086c575f80fd5b5035919050565b5f60208284031215610883575f80fd5b61088c826107e0565b9392505050565b5f80604083850312156108a4575f80fd5b6108ad836107e0565b91506108bb602084016107e0565b90509250929050565b600181811c908216806108d857607f821691505b6020821081036108f657634e487b7160e01b5f52602260045260245ffd5b50919050565b8082018082111561031657634e487b7160e01b5f52601160045260245ffdfea26469706673582212200faeda9384b73f91ffb85ed7b9833a133cb82bcc872135898d86ec72c55ff16d64736f6c63430008190033", +} + +// ExampleERC20DecimalsABI is the input ABI used to generate the binding from. +// Deprecated: Use ExampleERC20DecimalsMetaData.ABI instead. +var ExampleERC20DecimalsABI = ExampleERC20DecimalsMetaData.ABI + +// ExampleERC20DecimalsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ExampleERC20DecimalsMetaData.Bin instead. +var ExampleERC20DecimalsBin = ExampleERC20DecimalsMetaData.Bin + +// DeployExampleERC20Decimals deploys a new Ethereum contract, binding an instance of ExampleERC20Decimals to it. +func DeployExampleERC20Decimals(auth *bind.TransactOpts, backend bind.ContractBackend, tokenDecimals_ uint8) (common.Address, *types.Transaction, *ExampleERC20Decimals, error) { + parsed, err := ExampleERC20DecimalsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ExampleERC20DecimalsBin), backend, tokenDecimals_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ExampleERC20Decimals{ExampleERC20DecimalsCaller: ExampleERC20DecimalsCaller{contract: contract}, ExampleERC20DecimalsTransactor: ExampleERC20DecimalsTransactor{contract: contract}, ExampleERC20DecimalsFilterer: ExampleERC20DecimalsFilterer{contract: contract}}, nil +} + +// ExampleERC20Decimals is an auto generated Go binding around an Ethereum contract. +type ExampleERC20Decimals struct { + ExampleERC20DecimalsCaller // Read-only binding to the contract + ExampleERC20DecimalsTransactor // Write-only binding to the contract + ExampleERC20DecimalsFilterer // Log filterer for contract events +} + +// ExampleERC20DecimalsCaller is an auto generated read-only Go binding around an Ethereum contract. +type ExampleERC20DecimalsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleERC20DecimalsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ExampleERC20DecimalsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleERC20DecimalsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ExampleERC20DecimalsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleERC20DecimalsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ExampleERC20DecimalsSession struct { + Contract *ExampleERC20Decimals // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleERC20DecimalsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ExampleERC20DecimalsCallerSession struct { + Contract *ExampleERC20DecimalsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ExampleERC20DecimalsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ExampleERC20DecimalsTransactorSession struct { + Contract *ExampleERC20DecimalsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleERC20DecimalsRaw is an auto generated low-level Go binding around an Ethereum contract. +type ExampleERC20DecimalsRaw struct { + Contract *ExampleERC20Decimals // Generic contract binding to access the raw methods on +} + +// ExampleERC20DecimalsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ExampleERC20DecimalsCallerRaw struct { + Contract *ExampleERC20DecimalsCaller // Generic read-only contract binding to access the raw methods on +} + +// ExampleERC20DecimalsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ExampleERC20DecimalsTransactorRaw struct { + Contract *ExampleERC20DecimalsTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewExampleERC20Decimals creates a new instance of ExampleERC20Decimals, bound to a specific deployed contract. +func NewExampleERC20Decimals(address common.Address, backend bind.ContractBackend) (*ExampleERC20Decimals, error) { + contract, err := bindExampleERC20Decimals(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ExampleERC20Decimals{ExampleERC20DecimalsCaller: ExampleERC20DecimalsCaller{contract: contract}, ExampleERC20DecimalsTransactor: ExampleERC20DecimalsTransactor{contract: contract}, ExampleERC20DecimalsFilterer: ExampleERC20DecimalsFilterer{contract: contract}}, nil +} + +// NewExampleERC20DecimalsCaller creates a new read-only instance of ExampleERC20Decimals, bound to a specific deployed contract. +func NewExampleERC20DecimalsCaller(address common.Address, caller bind.ContractCaller) (*ExampleERC20DecimalsCaller, error) { + contract, err := bindExampleERC20Decimals(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ExampleERC20DecimalsCaller{contract: contract}, nil +} + +// NewExampleERC20DecimalsTransactor creates a new write-only instance of ExampleERC20Decimals, bound to a specific deployed contract. +func NewExampleERC20DecimalsTransactor(address common.Address, transactor bind.ContractTransactor) (*ExampleERC20DecimalsTransactor, error) { + contract, err := bindExampleERC20Decimals(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ExampleERC20DecimalsTransactor{contract: contract}, nil +} + +// NewExampleERC20DecimalsFilterer creates a new log filterer instance of ExampleERC20Decimals, bound to a specific deployed contract. +func NewExampleERC20DecimalsFilterer(address common.Address, filterer bind.ContractFilterer) (*ExampleERC20DecimalsFilterer, error) { + contract, err := bindExampleERC20Decimals(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ExampleERC20DecimalsFilterer{contract: contract}, nil +} + +// bindExampleERC20Decimals binds a generic wrapper to an already deployed contract. +func bindExampleERC20Decimals(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ExampleERC20DecimalsMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleERC20Decimals *ExampleERC20DecimalsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleERC20Decimals.Contract.ExampleERC20DecimalsCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleERC20Decimals *ExampleERC20DecimalsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.ExampleERC20DecimalsTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleERC20Decimals *ExampleERC20DecimalsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.ExampleERC20DecimalsTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleERC20Decimals.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _ExampleERC20Decimals.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ExampleERC20Decimals.Contract.Allowance(&_ExampleERC20Decimals.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ExampleERC20Decimals.Contract.Allowance(&_ExampleERC20Decimals.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _ExampleERC20Decimals.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ExampleERC20Decimals.Contract.BalanceOf(&_ExampleERC20Decimals.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ExampleERC20Decimals.Contract.BalanceOf(&_ExampleERC20Decimals.CallOpts, account) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ExampleERC20Decimals.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Decimals() (uint8, error) { + return _ExampleERC20Decimals.Contract.Decimals(&_ExampleERC20Decimals.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerSession) Decimals() (uint8, error) { + return _ExampleERC20Decimals.Contract.Decimals(&_ExampleERC20Decimals.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ExampleERC20Decimals.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Name() (string, error) { + return _ExampleERC20Decimals.Contract.Name(&_ExampleERC20Decimals.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerSession) Name() (string, error) { + return _ExampleERC20Decimals.Contract.Name(&_ExampleERC20Decimals.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ExampleERC20Decimals.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Symbol() (string, error) { + return _ExampleERC20Decimals.Contract.Symbol(&_ExampleERC20Decimals.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerSession) Symbol() (string, error) { + return _ExampleERC20Decimals.Contract.Symbol(&_ExampleERC20Decimals.CallOpts) +} + +// TokenDecimals is a free data retrieval call binding the contract method 0x3b97e856. +// +// Solidity: function tokenDecimals() view returns(uint8) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCaller) TokenDecimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ExampleERC20Decimals.contract.Call(opts, &out, "tokenDecimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// TokenDecimals is a free data retrieval call binding the contract method 0x3b97e856. +// +// Solidity: function tokenDecimals() view returns(uint8) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) TokenDecimals() (uint8, error) { + return _ExampleERC20Decimals.Contract.TokenDecimals(&_ExampleERC20Decimals.CallOpts) +} + +// TokenDecimals is a free data retrieval call binding the contract method 0x3b97e856. +// +// Solidity: function tokenDecimals() view returns(uint8) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerSession) TokenDecimals() (uint8, error) { + return _ExampleERC20Decimals.Contract.TokenDecimals(&_ExampleERC20Decimals.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ExampleERC20Decimals.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) TotalSupply() (*big.Int, error) { + return _ExampleERC20Decimals.Contract.TotalSupply(&_ExampleERC20Decimals.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ExampleERC20Decimals *ExampleERC20DecimalsCallerSession) TotalSupply() (*big.Int, error) { + return _ExampleERC20Decimals.Contract.TotalSupply(&_ExampleERC20Decimals.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Approve(&_ExampleERC20Decimals.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Approve(&_ExampleERC20Decimals.TransactOpts, spender, value) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 value) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactor) Burn(opts *bind.TransactOpts, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.contract.Transact(opts, "burn", value) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 value) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Burn(value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Burn(&_ExampleERC20Decimals.TransactOpts, value) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 value) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorSession) Burn(value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Burn(&_ExampleERC20Decimals.TransactOpts, value) +} + +// BurnFrom is a paid mutator transaction binding the contract method 0x79cc6790. +// +// Solidity: function burnFrom(address account, uint256 value) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactor) BurnFrom(opts *bind.TransactOpts, account common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.contract.Transact(opts, "burnFrom", account, value) +} + +// BurnFrom is a paid mutator transaction binding the contract method 0x79cc6790. +// +// Solidity: function burnFrom(address account, uint256 value) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) BurnFrom(account common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.BurnFrom(&_ExampleERC20Decimals.TransactOpts, account, value) +} + +// BurnFrom is a paid mutator transaction binding the contract method 0x79cc6790. +// +// Solidity: function burnFrom(address account, uint256 value) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorSession) BurnFrom(account common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.BurnFrom(&_ExampleERC20Decimals.TransactOpts, account, value) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.contract.Transact(opts, "mint", account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Mint(&_ExampleERC20Decimals.TransactOpts, account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Mint(&_ExampleERC20Decimals.TransactOpts, account, amount) +} + +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. +// +// Solidity: function mint(uint256 amount) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactor) Mint0(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.contract.Transact(opts, "mint0", amount) +} + +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. +// +// Solidity: function mint(uint256 amount) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Mint0(amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Mint0(&_ExampleERC20Decimals.TransactOpts, amount) +} + +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. +// +// Solidity: function mint(uint256 amount) returns() +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorSession) Mint0(amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Mint0(&_ExampleERC20Decimals.TransactOpts, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Transfer(&_ExampleERC20Decimals.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.Transfer(&_ExampleERC20Decimals.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.TransferFrom(&_ExampleERC20Decimals.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ExampleERC20Decimals *ExampleERC20DecimalsTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20Decimals.Contract.TransferFrom(&_ExampleERC20Decimals.TransactOpts, from, to, value) +} + +// ExampleERC20DecimalsApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the ExampleERC20Decimals contract. +type ExampleERC20DecimalsApprovalIterator struct { + Event *ExampleERC20DecimalsApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ExampleERC20DecimalsApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ExampleERC20DecimalsApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ExampleERC20DecimalsApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ExampleERC20DecimalsApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ExampleERC20DecimalsApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ExampleERC20DecimalsApproval represents a Approval event raised by the ExampleERC20Decimals contract. +type ExampleERC20DecimalsApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ExampleERC20Decimals *ExampleERC20DecimalsFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ExampleERC20DecimalsApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ExampleERC20Decimals.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ExampleERC20DecimalsApprovalIterator{contract: _ExampleERC20Decimals.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ExampleERC20Decimals *ExampleERC20DecimalsFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ExampleERC20DecimalsApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ExampleERC20Decimals.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ExampleERC20DecimalsApproval) + if err := _ExampleERC20Decimals.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ExampleERC20Decimals *ExampleERC20DecimalsFilterer) ParseApproval(log types.Log) (*ExampleERC20DecimalsApproval, error) { + event := new(ExampleERC20DecimalsApproval) + if err := _ExampleERC20Decimals.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ExampleERC20DecimalsTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ExampleERC20Decimals contract. +type ExampleERC20DecimalsTransferIterator struct { + Event *ExampleERC20DecimalsTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ExampleERC20DecimalsTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ExampleERC20DecimalsTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ExampleERC20DecimalsTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ExampleERC20DecimalsTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ExampleERC20DecimalsTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ExampleERC20DecimalsTransfer represents a Transfer event raised by the ExampleERC20Decimals contract. +type ExampleERC20DecimalsTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ExampleERC20Decimals *ExampleERC20DecimalsFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ExampleERC20DecimalsTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ExampleERC20Decimals.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &ExampleERC20DecimalsTransferIterator{contract: _ExampleERC20Decimals.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ExampleERC20Decimals *ExampleERC20DecimalsFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ExampleERC20DecimalsTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ExampleERC20Decimals.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ExampleERC20DecimalsTransfer) + if err := _ExampleERC20Decimals.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ExampleERC20Decimals *ExampleERC20DecimalsFilterer) ParseTransfer(log types.Log) (*ExampleERC20DecimalsTransfer, error) { + event := new(ExampleERC20DecimalsTransfer) + if err := _ExampleERC20Decimals.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/mocks/MockERC20SendAndCallReceiver/MockERC20SendAndCallReceiver.go b/abi-bindings/go/ictt/mocks/MockERC20SendAndCallReceiver/MockERC20SendAndCallReceiver.go new file mode 100644 index 000000000..7418c6171 --- /dev/null +++ b/abi-bindings/go/ictt/mocks/MockERC20SendAndCallReceiver/MockERC20SendAndCallReceiver.go @@ -0,0 +1,441 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mockerc20sendandcallreceiver + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// MockERC20SendAndCallReceiverMetaData contains all meta data concerning the MockERC20SendAndCallReceiver contract. +var MockERC20SendAndCallReceiverMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"TokensReceived\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"blockedSenders\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"blocked\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"receiveTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600e575f80fd5b506107608061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c8063487bd69e146100435780637f450d8d1461008157806394395edd146100be575b5f80fd5b61006d610051366004610589565b5f60208181529281526040808220909352908152205460ff1681565b604051901515815260200160405180910390f35b6100bc61008f366004610589565b5f918252602082815260408084206001600160a01b0390931684529190529020805460ff19166001179055565b005b6100bc6100cc3660046105b3565b5f878152602081815260408083206001600160a01b038916845290915290205460ff16156101565760405162461bcd60e51b815260206004820152602c60248201527f4d6f636b455243323053656e64416e6443616c6c52656365697665723a20736560448201526b1b99195c88189b1bd8dad95960a21b60648201526084015b60405180910390fd5b846001600160a01b0316866001600160a01b0316887f7149eb81ada224b86bfda05a4cf439b25596d3c0d8015aebd1cdc11ab17fe190878787876040516101a09493929190610662565b60405180910390a4806102095760405162461bcd60e51b815260206004820152602b60248201527f4d6f636b455243323053656e64416e6443616c6c52656365697665723a20656d60448201526a1c1d1e481c185e5b1bd85960aa1b606482015260840161014d565b61021484338561021e565b5050505050505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa158015610264573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061028891906106a9565b905061029f6001600160a01b038616853086610383565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa1580156102e3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061030791906106a9565b905081811161036d5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840161014d565b61037782826106c0565b925050505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526103dd9085906103e3565b50505050565b5f6103f76001600160a01b03841683610449565b905080515f1415801561041b57508080602001905181019061041991906106df565b155b1561044457604051635274afe760e01b81526001600160a01b038416600482015260240161014d565b505050565b606061045683835f61045f565b90505b92915050565b6060814710156104845760405163cd78605960e01b815230600482015260240161014d565b5f80856001600160a01b0316848660405161049f91906106fe565b5f6040518083038185875af1925050503d805f81146104d9576040519150601f19603f3d011682016040523d82523d5f602084013e6104de565b606091505b50915091506103778683836060826104fe576104f982610545565b61037c565b815115801561051557506001600160a01b0384163b155b1561053e57604051639996b31560e01b81526001600160a01b038516600482015260240161014d565b508061037c565b8051156105555780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b0381168114610584575f80fd5b919050565b5f806040838503121561059a575f80fd5b823591506105aa6020840161056e565b90509250929050565b5f805f805f805f60c0888a0312156105c9575f80fd5b873596506105d96020890161056e565b95506105e76040890161056e565b94506105f56060890161056e565b93506080880135925060a088013567ffffffffffffffff80821115610618575f80fd5b818a0191508a601f83011261062b575f80fd5b813581811115610639575f80fd5b8b602082850101111561064a575f80fd5b60208301945080935050505092959891949750929550565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301375f818301608090810191909152601f909201601f191601019392505050565b5f602082840312156106b9575f80fd5b5051919050565b8181038181111561045957634e487b7160e01b5f52601160045260245ffd5b5f602082840312156106ef575f80fd5b8151801515811461037c575f80fd5b5f82515f5b8181101561071d5760208186018101518583015201610703565b505f92019182525091905056fea2646970667358221220d49b2770f6cd144581c44b54ff002ad3a20db8f8f48068ef826d55bbc8553ea564736f6c63430008190033", +} + +// MockERC20SendAndCallReceiverABI is the input ABI used to generate the binding from. +// Deprecated: Use MockERC20SendAndCallReceiverMetaData.ABI instead. +var MockERC20SendAndCallReceiverABI = MockERC20SendAndCallReceiverMetaData.ABI + +// MockERC20SendAndCallReceiverBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MockERC20SendAndCallReceiverMetaData.Bin instead. +var MockERC20SendAndCallReceiverBin = MockERC20SendAndCallReceiverMetaData.Bin + +// DeployMockERC20SendAndCallReceiver deploys a new Ethereum contract, binding an instance of MockERC20SendAndCallReceiver to it. +func DeployMockERC20SendAndCallReceiver(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MockERC20SendAndCallReceiver, error) { + parsed, err := MockERC20SendAndCallReceiverMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockERC20SendAndCallReceiverBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockERC20SendAndCallReceiver{MockERC20SendAndCallReceiverCaller: MockERC20SendAndCallReceiverCaller{contract: contract}, MockERC20SendAndCallReceiverTransactor: MockERC20SendAndCallReceiverTransactor{contract: contract}, MockERC20SendAndCallReceiverFilterer: MockERC20SendAndCallReceiverFilterer{contract: contract}}, nil +} + +// MockERC20SendAndCallReceiver is an auto generated Go binding around an Ethereum contract. +type MockERC20SendAndCallReceiver struct { + MockERC20SendAndCallReceiverCaller // Read-only binding to the contract + MockERC20SendAndCallReceiverTransactor // Write-only binding to the contract + MockERC20SendAndCallReceiverFilterer // Log filterer for contract events +} + +// MockERC20SendAndCallReceiverCaller is an auto generated read-only Go binding around an Ethereum contract. +type MockERC20SendAndCallReceiverCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockERC20SendAndCallReceiverTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MockERC20SendAndCallReceiverTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockERC20SendAndCallReceiverFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MockERC20SendAndCallReceiverFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockERC20SendAndCallReceiverSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MockERC20SendAndCallReceiverSession struct { + Contract *MockERC20SendAndCallReceiver // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MockERC20SendAndCallReceiverCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MockERC20SendAndCallReceiverCallerSession struct { + Contract *MockERC20SendAndCallReceiverCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MockERC20SendAndCallReceiverTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MockERC20SendAndCallReceiverTransactorSession struct { + Contract *MockERC20SendAndCallReceiverTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MockERC20SendAndCallReceiverRaw is an auto generated low-level Go binding around an Ethereum contract. +type MockERC20SendAndCallReceiverRaw struct { + Contract *MockERC20SendAndCallReceiver // Generic contract binding to access the raw methods on +} + +// MockERC20SendAndCallReceiverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MockERC20SendAndCallReceiverCallerRaw struct { + Contract *MockERC20SendAndCallReceiverCaller // Generic read-only contract binding to access the raw methods on +} + +// MockERC20SendAndCallReceiverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MockERC20SendAndCallReceiverTransactorRaw struct { + Contract *MockERC20SendAndCallReceiverTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewMockERC20SendAndCallReceiver creates a new instance of MockERC20SendAndCallReceiver, bound to a specific deployed contract. +func NewMockERC20SendAndCallReceiver(address common.Address, backend bind.ContractBackend) (*MockERC20SendAndCallReceiver, error) { + contract, err := bindMockERC20SendAndCallReceiver(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockERC20SendAndCallReceiver{MockERC20SendAndCallReceiverCaller: MockERC20SendAndCallReceiverCaller{contract: contract}, MockERC20SendAndCallReceiverTransactor: MockERC20SendAndCallReceiverTransactor{contract: contract}, MockERC20SendAndCallReceiverFilterer: MockERC20SendAndCallReceiverFilterer{contract: contract}}, nil +} + +// NewMockERC20SendAndCallReceiverCaller creates a new read-only instance of MockERC20SendAndCallReceiver, bound to a specific deployed contract. +func NewMockERC20SendAndCallReceiverCaller(address common.Address, caller bind.ContractCaller) (*MockERC20SendAndCallReceiverCaller, error) { + contract, err := bindMockERC20SendAndCallReceiver(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockERC20SendAndCallReceiverCaller{contract: contract}, nil +} + +// NewMockERC20SendAndCallReceiverTransactor creates a new write-only instance of MockERC20SendAndCallReceiver, bound to a specific deployed contract. +func NewMockERC20SendAndCallReceiverTransactor(address common.Address, transactor bind.ContractTransactor) (*MockERC20SendAndCallReceiverTransactor, error) { + contract, err := bindMockERC20SendAndCallReceiver(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockERC20SendAndCallReceiverTransactor{contract: contract}, nil +} + +// NewMockERC20SendAndCallReceiverFilterer creates a new log filterer instance of MockERC20SendAndCallReceiver, bound to a specific deployed contract. +func NewMockERC20SendAndCallReceiverFilterer(address common.Address, filterer bind.ContractFilterer) (*MockERC20SendAndCallReceiverFilterer, error) { + contract, err := bindMockERC20SendAndCallReceiver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockERC20SendAndCallReceiverFilterer{contract: contract}, nil +} + +// bindMockERC20SendAndCallReceiver binds a generic wrapper to an already deployed contract. +func bindMockERC20SendAndCallReceiver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockERC20SendAndCallReceiverMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockERC20SendAndCallReceiver.Contract.MockERC20SendAndCallReceiverCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.MockERC20SendAndCallReceiverTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.MockERC20SendAndCallReceiverTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockERC20SendAndCallReceiver.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.contract.Transact(opts, method, params...) +} + +// BlockedSenders is a free data retrieval call binding the contract method 0x487bd69e. +// +// Solidity: function blockedSenders(bytes32 blockchainID, address senderAddress) view returns(bool blocked) +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverCaller) BlockedSenders(opts *bind.CallOpts, blockchainID [32]byte, senderAddress common.Address) (bool, error) { + var out []interface{} + err := _MockERC20SendAndCallReceiver.contract.Call(opts, &out, "blockedSenders", blockchainID, senderAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// BlockedSenders is a free data retrieval call binding the contract method 0x487bd69e. +// +// Solidity: function blockedSenders(bytes32 blockchainID, address senderAddress) view returns(bool blocked) +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverSession) BlockedSenders(blockchainID [32]byte, senderAddress common.Address) (bool, error) { + return _MockERC20SendAndCallReceiver.Contract.BlockedSenders(&_MockERC20SendAndCallReceiver.CallOpts, blockchainID, senderAddress) +} + +// BlockedSenders is a free data retrieval call binding the contract method 0x487bd69e. +// +// Solidity: function blockedSenders(bytes32 blockchainID, address senderAddress) view returns(bool blocked) +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverCallerSession) BlockedSenders(blockchainID [32]byte, senderAddress common.Address) (bool, error) { + return _MockERC20SendAndCallReceiver.Contract.BlockedSenders(&_MockERC20SendAndCallReceiver.CallOpts, blockchainID, senderAddress) +} + +// BlockSender is a paid mutator transaction binding the contract method 0x7f450d8d. +// +// Solidity: function blockSender(bytes32 blockchainID, address senderAddress) returns() +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverTransactor) BlockSender(opts *bind.TransactOpts, blockchainID [32]byte, senderAddress common.Address) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.contract.Transact(opts, "blockSender", blockchainID, senderAddress) +} + +// BlockSender is a paid mutator transaction binding the contract method 0x7f450d8d. +// +// Solidity: function blockSender(bytes32 blockchainID, address senderAddress) returns() +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverSession) BlockSender(blockchainID [32]byte, senderAddress common.Address) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.BlockSender(&_MockERC20SendAndCallReceiver.TransactOpts, blockchainID, senderAddress) +} + +// BlockSender is a paid mutator transaction binding the contract method 0x7f450d8d. +// +// Solidity: function blockSender(bytes32 blockchainID, address senderAddress) returns() +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverTransactorSession) BlockSender(blockchainID [32]byte, senderAddress common.Address) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.BlockSender(&_MockERC20SendAndCallReceiver.TransactOpts, blockchainID, senderAddress) +} + +// ReceiveTokens is a paid mutator transaction binding the contract method 0x94395edd. +// +// Solidity: function receiveTokens(bytes32 sourceBlockchainID, address originTokenTransferrerAddress, address originSenderAddress, address token, uint256 amount, bytes payload) returns() +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverTransactor) ReceiveTokens(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originTokenTransferrerAddress common.Address, originSenderAddress common.Address, token common.Address, amount *big.Int, payload []byte) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.contract.Transact(opts, "receiveTokens", sourceBlockchainID, originTokenTransferrerAddress, originSenderAddress, token, amount, payload) +} + +// ReceiveTokens is a paid mutator transaction binding the contract method 0x94395edd. +// +// Solidity: function receiveTokens(bytes32 sourceBlockchainID, address originTokenTransferrerAddress, address originSenderAddress, address token, uint256 amount, bytes payload) returns() +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverSession) ReceiveTokens(sourceBlockchainID [32]byte, originTokenTransferrerAddress common.Address, originSenderAddress common.Address, token common.Address, amount *big.Int, payload []byte) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.ReceiveTokens(&_MockERC20SendAndCallReceiver.TransactOpts, sourceBlockchainID, originTokenTransferrerAddress, originSenderAddress, token, amount, payload) +} + +// ReceiveTokens is a paid mutator transaction binding the contract method 0x94395edd. +// +// Solidity: function receiveTokens(bytes32 sourceBlockchainID, address originTokenTransferrerAddress, address originSenderAddress, address token, uint256 amount, bytes payload) returns() +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverTransactorSession) ReceiveTokens(sourceBlockchainID [32]byte, originTokenTransferrerAddress common.Address, originSenderAddress common.Address, token common.Address, amount *big.Int, payload []byte) (*types.Transaction, error) { + return _MockERC20SendAndCallReceiver.Contract.ReceiveTokens(&_MockERC20SendAndCallReceiver.TransactOpts, sourceBlockchainID, originTokenTransferrerAddress, originSenderAddress, token, amount, payload) +} + +// MockERC20SendAndCallReceiverTokensReceivedIterator is returned from FilterTokensReceived and is used to iterate over the raw logs and unpacked data for TokensReceived events raised by the MockERC20SendAndCallReceiver contract. +type MockERC20SendAndCallReceiverTokensReceivedIterator struct { + Event *MockERC20SendAndCallReceiverTokensReceived // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MockERC20SendAndCallReceiverTokensReceivedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockERC20SendAndCallReceiverTokensReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MockERC20SendAndCallReceiverTokensReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MockERC20SendAndCallReceiverTokensReceivedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MockERC20SendAndCallReceiverTokensReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MockERC20SendAndCallReceiverTokensReceived represents a TokensReceived event raised by the MockERC20SendAndCallReceiver contract. +type MockERC20SendAndCallReceiverTokensReceived struct { + SourceBlockchainID [32]byte + OriginTokenTransferrerAddress common.Address + OriginSenderAddress common.Address + Token common.Address + Amount *big.Int + Payload []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensReceived is a free log retrieval operation binding the contract event 0x7149eb81ada224b86bfda05a4cf439b25596d3c0d8015aebd1cdc11ab17fe190. +// +// Solidity: event TokensReceived(bytes32 indexed sourceBlockchainID, address indexed originTokenTransferrerAddress, address indexed originSenderAddress, address token, uint256 amount, bytes payload) +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverFilterer) FilterTokensReceived(opts *bind.FilterOpts, sourceBlockchainID [][32]byte, originTokenTransferrerAddress []common.Address, originSenderAddress []common.Address) (*MockERC20SendAndCallReceiverTokensReceivedIterator, error) { + + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var originTokenTransferrerAddressRule []interface{} + for _, originTokenTransferrerAddressItem := range originTokenTransferrerAddress { + originTokenTransferrerAddressRule = append(originTokenTransferrerAddressRule, originTokenTransferrerAddressItem) + } + var originSenderAddressRule []interface{} + for _, originSenderAddressItem := range originSenderAddress { + originSenderAddressRule = append(originSenderAddressRule, originSenderAddressItem) + } + + logs, sub, err := _MockERC20SendAndCallReceiver.contract.FilterLogs(opts, "TokensReceived", sourceBlockchainIDRule, originTokenTransferrerAddressRule, originSenderAddressRule) + if err != nil { + return nil, err + } + return &MockERC20SendAndCallReceiverTokensReceivedIterator{contract: _MockERC20SendAndCallReceiver.contract, event: "TokensReceived", logs: logs, sub: sub}, nil +} + +// WatchTokensReceived is a free log subscription operation binding the contract event 0x7149eb81ada224b86bfda05a4cf439b25596d3c0d8015aebd1cdc11ab17fe190. +// +// Solidity: event TokensReceived(bytes32 indexed sourceBlockchainID, address indexed originTokenTransferrerAddress, address indexed originSenderAddress, address token, uint256 amount, bytes payload) +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverFilterer) WatchTokensReceived(opts *bind.WatchOpts, sink chan<- *MockERC20SendAndCallReceiverTokensReceived, sourceBlockchainID [][32]byte, originTokenTransferrerAddress []common.Address, originSenderAddress []common.Address) (event.Subscription, error) { + + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var originTokenTransferrerAddressRule []interface{} + for _, originTokenTransferrerAddressItem := range originTokenTransferrerAddress { + originTokenTransferrerAddressRule = append(originTokenTransferrerAddressRule, originTokenTransferrerAddressItem) + } + var originSenderAddressRule []interface{} + for _, originSenderAddressItem := range originSenderAddress { + originSenderAddressRule = append(originSenderAddressRule, originSenderAddressItem) + } + + logs, sub, err := _MockERC20SendAndCallReceiver.contract.WatchLogs(opts, "TokensReceived", sourceBlockchainIDRule, originTokenTransferrerAddressRule, originSenderAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MockERC20SendAndCallReceiverTokensReceived) + if err := _MockERC20SendAndCallReceiver.contract.UnpackLog(event, "TokensReceived", 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 +} + +// ParseTokensReceived is a log parse operation binding the contract event 0x7149eb81ada224b86bfda05a4cf439b25596d3c0d8015aebd1cdc11ab17fe190. +// +// Solidity: event TokensReceived(bytes32 indexed sourceBlockchainID, address indexed originTokenTransferrerAddress, address indexed originSenderAddress, address token, uint256 amount, bytes payload) +func (_MockERC20SendAndCallReceiver *MockERC20SendAndCallReceiverFilterer) ParseTokensReceived(log types.Log) (*MockERC20SendAndCallReceiverTokensReceived, error) { + event := new(MockERC20SendAndCallReceiverTokensReceived) + if err := _MockERC20SendAndCallReceiver.contract.UnpackLog(event, "TokensReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ictt/mocks/MockNativeSendAndCallReceiver/MockNativeSendAndCallReceiver.go b/abi-bindings/go/ictt/mocks/MockNativeSendAndCallReceiver/MockNativeSendAndCallReceiver.go new file mode 100644 index 000000000..c1a540346 --- /dev/null +++ b/abi-bindings/go/ictt/mocks/MockNativeSendAndCallReceiver/MockNativeSendAndCallReceiver.go @@ -0,0 +1,440 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mocknativesendandcallreceiver + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// MockNativeSendAndCallReceiverMetaData contains all meta data concerning the MockNativeSendAndCallReceiver contract. +var MockNativeSendAndCallReceiverMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originTokenTransferrerAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"TokensReceived\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"blockedSenders\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"blocked\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originTokenTransferrerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"receiveTokens\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600e575f80fd5b506103678061001c5f395ff3fe608060405260043610610033575f3560e01c80632c3625fe14610037578063487bd69e1461004c5780637f450d8d14610096575b5f80fd5b61004a61004536600461023f565b6100dd565b005b348015610057575f80fd5b506100826100663660046102d2565b5f60208181529281526040808220909352908152205460ff1681565b604051901515815260200160405180910390f35b3480156100a1575f80fd5b5061004a6100b03660046102d2565b5f918252602082815260408084206001600160a01b0390931684529190529020805460ff19166001179055565b5f858152602081815260408083206001600160a01b038716845290915290205460ff16156101685760405162461bcd60e51b815260206004820152602d60248201527f4d6f636b4e617469766553656e64416e6443616c6c52656365697665723a207360448201526c195b99195c88189b1bd8dad959609a1b60648201526084015b60405180910390fd5b826001600160a01b0316846001600160a01b0316867f98f64f0ad4e0e2a42535fa15b05dc6e800e16e439c98143fefabb72b43bad53e3486866040516101b0939291906102fc565b60405180910390a45f81900361021d5760405162461bcd60e51b815260206004820152602c60248201527f4d6f636b4e617469766553656e64416e6443616c6c52656365697665723a206560448201526b1b5c1d1e481c185e5b1bd85960a21b606482015260840161015f565b5050505050565b80356001600160a01b038116811461023a575f80fd5b919050565b5f805f805f60808688031215610253575f80fd5b8535945061026360208701610224565b935061027160408701610224565b9250606086013567ffffffffffffffff8082111561028d575f80fd5b818801915088601f8301126102a0575f80fd5b8135818111156102ae575f80fd5b8960208285010111156102bf575f80fd5b9699959850939650602001949392505050565b5f80604083850312156102e3575f80fd5b823591506102f360208401610224565b90509250929050565b83815260406020820152816040820152818360608301375f818301606090810191909152601f909201601f191601019291505056fea26469706673582212206e71f161cae5c266fd6be5090edfe6ae227f4000978cf1b2e76f6c7ded2372bd64736f6c63430008190033", +} + +// MockNativeSendAndCallReceiverABI is the input ABI used to generate the binding from. +// Deprecated: Use MockNativeSendAndCallReceiverMetaData.ABI instead. +var MockNativeSendAndCallReceiverABI = MockNativeSendAndCallReceiverMetaData.ABI + +// MockNativeSendAndCallReceiverBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MockNativeSendAndCallReceiverMetaData.Bin instead. +var MockNativeSendAndCallReceiverBin = MockNativeSendAndCallReceiverMetaData.Bin + +// DeployMockNativeSendAndCallReceiver deploys a new Ethereum contract, binding an instance of MockNativeSendAndCallReceiver to it. +func DeployMockNativeSendAndCallReceiver(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MockNativeSendAndCallReceiver, error) { + parsed, err := MockNativeSendAndCallReceiverMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MockNativeSendAndCallReceiverBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockNativeSendAndCallReceiver{MockNativeSendAndCallReceiverCaller: MockNativeSendAndCallReceiverCaller{contract: contract}, MockNativeSendAndCallReceiverTransactor: MockNativeSendAndCallReceiverTransactor{contract: contract}, MockNativeSendAndCallReceiverFilterer: MockNativeSendAndCallReceiverFilterer{contract: contract}}, nil +} + +// MockNativeSendAndCallReceiver is an auto generated Go binding around an Ethereum contract. +type MockNativeSendAndCallReceiver struct { + MockNativeSendAndCallReceiverCaller // Read-only binding to the contract + MockNativeSendAndCallReceiverTransactor // Write-only binding to the contract + MockNativeSendAndCallReceiverFilterer // Log filterer for contract events +} + +// MockNativeSendAndCallReceiverCaller is an auto generated read-only Go binding around an Ethereum contract. +type MockNativeSendAndCallReceiverCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockNativeSendAndCallReceiverTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MockNativeSendAndCallReceiverTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockNativeSendAndCallReceiverFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MockNativeSendAndCallReceiverFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockNativeSendAndCallReceiverSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MockNativeSendAndCallReceiverSession struct { + Contract *MockNativeSendAndCallReceiver // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MockNativeSendAndCallReceiverCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MockNativeSendAndCallReceiverCallerSession struct { + Contract *MockNativeSendAndCallReceiverCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MockNativeSendAndCallReceiverTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MockNativeSendAndCallReceiverTransactorSession struct { + Contract *MockNativeSendAndCallReceiverTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MockNativeSendAndCallReceiverRaw is an auto generated low-level Go binding around an Ethereum contract. +type MockNativeSendAndCallReceiverRaw struct { + Contract *MockNativeSendAndCallReceiver // Generic contract binding to access the raw methods on +} + +// MockNativeSendAndCallReceiverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MockNativeSendAndCallReceiverCallerRaw struct { + Contract *MockNativeSendAndCallReceiverCaller // Generic read-only contract binding to access the raw methods on +} + +// MockNativeSendAndCallReceiverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MockNativeSendAndCallReceiverTransactorRaw struct { + Contract *MockNativeSendAndCallReceiverTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewMockNativeSendAndCallReceiver creates a new instance of MockNativeSendAndCallReceiver, bound to a specific deployed contract. +func NewMockNativeSendAndCallReceiver(address common.Address, backend bind.ContractBackend) (*MockNativeSendAndCallReceiver, error) { + contract, err := bindMockNativeSendAndCallReceiver(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockNativeSendAndCallReceiver{MockNativeSendAndCallReceiverCaller: MockNativeSendAndCallReceiverCaller{contract: contract}, MockNativeSendAndCallReceiverTransactor: MockNativeSendAndCallReceiverTransactor{contract: contract}, MockNativeSendAndCallReceiverFilterer: MockNativeSendAndCallReceiverFilterer{contract: contract}}, nil +} + +// NewMockNativeSendAndCallReceiverCaller creates a new read-only instance of MockNativeSendAndCallReceiver, bound to a specific deployed contract. +func NewMockNativeSendAndCallReceiverCaller(address common.Address, caller bind.ContractCaller) (*MockNativeSendAndCallReceiverCaller, error) { + contract, err := bindMockNativeSendAndCallReceiver(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockNativeSendAndCallReceiverCaller{contract: contract}, nil +} + +// NewMockNativeSendAndCallReceiverTransactor creates a new write-only instance of MockNativeSendAndCallReceiver, bound to a specific deployed contract. +func NewMockNativeSendAndCallReceiverTransactor(address common.Address, transactor bind.ContractTransactor) (*MockNativeSendAndCallReceiverTransactor, error) { + contract, err := bindMockNativeSendAndCallReceiver(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockNativeSendAndCallReceiverTransactor{contract: contract}, nil +} + +// NewMockNativeSendAndCallReceiverFilterer creates a new log filterer instance of MockNativeSendAndCallReceiver, bound to a specific deployed contract. +func NewMockNativeSendAndCallReceiverFilterer(address common.Address, filterer bind.ContractFilterer) (*MockNativeSendAndCallReceiverFilterer, error) { + contract, err := bindMockNativeSendAndCallReceiver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockNativeSendAndCallReceiverFilterer{contract: contract}, nil +} + +// bindMockNativeSendAndCallReceiver binds a generic wrapper to an already deployed contract. +func bindMockNativeSendAndCallReceiver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockNativeSendAndCallReceiverMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockNativeSendAndCallReceiver.Contract.MockNativeSendAndCallReceiverCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.MockNativeSendAndCallReceiverTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.MockNativeSendAndCallReceiverTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockNativeSendAndCallReceiver.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.contract.Transact(opts, method, params...) +} + +// BlockedSenders is a free data retrieval call binding the contract method 0x487bd69e. +// +// Solidity: function blockedSenders(bytes32 blockchainID, address senderAddress) view returns(bool blocked) +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverCaller) BlockedSenders(opts *bind.CallOpts, blockchainID [32]byte, senderAddress common.Address) (bool, error) { + var out []interface{} + err := _MockNativeSendAndCallReceiver.contract.Call(opts, &out, "blockedSenders", blockchainID, senderAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// BlockedSenders is a free data retrieval call binding the contract method 0x487bd69e. +// +// Solidity: function blockedSenders(bytes32 blockchainID, address senderAddress) view returns(bool blocked) +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverSession) BlockedSenders(blockchainID [32]byte, senderAddress common.Address) (bool, error) { + return _MockNativeSendAndCallReceiver.Contract.BlockedSenders(&_MockNativeSendAndCallReceiver.CallOpts, blockchainID, senderAddress) +} + +// BlockedSenders is a free data retrieval call binding the contract method 0x487bd69e. +// +// Solidity: function blockedSenders(bytes32 blockchainID, address senderAddress) view returns(bool blocked) +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverCallerSession) BlockedSenders(blockchainID [32]byte, senderAddress common.Address) (bool, error) { + return _MockNativeSendAndCallReceiver.Contract.BlockedSenders(&_MockNativeSendAndCallReceiver.CallOpts, blockchainID, senderAddress) +} + +// BlockSender is a paid mutator transaction binding the contract method 0x7f450d8d. +// +// Solidity: function blockSender(bytes32 blockchainID, address senderAddress) returns() +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverTransactor) BlockSender(opts *bind.TransactOpts, blockchainID [32]byte, senderAddress common.Address) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.contract.Transact(opts, "blockSender", blockchainID, senderAddress) +} + +// BlockSender is a paid mutator transaction binding the contract method 0x7f450d8d. +// +// Solidity: function blockSender(bytes32 blockchainID, address senderAddress) returns() +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverSession) BlockSender(blockchainID [32]byte, senderAddress common.Address) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.BlockSender(&_MockNativeSendAndCallReceiver.TransactOpts, blockchainID, senderAddress) +} + +// BlockSender is a paid mutator transaction binding the contract method 0x7f450d8d. +// +// Solidity: function blockSender(bytes32 blockchainID, address senderAddress) returns() +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverTransactorSession) BlockSender(blockchainID [32]byte, senderAddress common.Address) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.BlockSender(&_MockNativeSendAndCallReceiver.TransactOpts, blockchainID, senderAddress) +} + +// ReceiveTokens is a paid mutator transaction binding the contract method 0x2c3625fe. +// +// Solidity: function receiveTokens(bytes32 sourceBlockchainID, address originTokenTransferrerAddress, address originSenderAddress, bytes payload) payable returns() +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverTransactor) ReceiveTokens(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originTokenTransferrerAddress common.Address, originSenderAddress common.Address, payload []byte) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.contract.Transact(opts, "receiveTokens", sourceBlockchainID, originTokenTransferrerAddress, originSenderAddress, payload) +} + +// ReceiveTokens is a paid mutator transaction binding the contract method 0x2c3625fe. +// +// Solidity: function receiveTokens(bytes32 sourceBlockchainID, address originTokenTransferrerAddress, address originSenderAddress, bytes payload) payable returns() +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverSession) ReceiveTokens(sourceBlockchainID [32]byte, originTokenTransferrerAddress common.Address, originSenderAddress common.Address, payload []byte) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.ReceiveTokens(&_MockNativeSendAndCallReceiver.TransactOpts, sourceBlockchainID, originTokenTransferrerAddress, originSenderAddress, payload) +} + +// ReceiveTokens is a paid mutator transaction binding the contract method 0x2c3625fe. +// +// Solidity: function receiveTokens(bytes32 sourceBlockchainID, address originTokenTransferrerAddress, address originSenderAddress, bytes payload) payable returns() +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverTransactorSession) ReceiveTokens(sourceBlockchainID [32]byte, originTokenTransferrerAddress common.Address, originSenderAddress common.Address, payload []byte) (*types.Transaction, error) { + return _MockNativeSendAndCallReceiver.Contract.ReceiveTokens(&_MockNativeSendAndCallReceiver.TransactOpts, sourceBlockchainID, originTokenTransferrerAddress, originSenderAddress, payload) +} + +// MockNativeSendAndCallReceiverTokensReceivedIterator is returned from FilterTokensReceived and is used to iterate over the raw logs and unpacked data for TokensReceived events raised by the MockNativeSendAndCallReceiver contract. +type MockNativeSendAndCallReceiverTokensReceivedIterator struct { + Event *MockNativeSendAndCallReceiverTokensReceived // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MockNativeSendAndCallReceiverTokensReceivedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MockNativeSendAndCallReceiverTokensReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MockNativeSendAndCallReceiverTokensReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MockNativeSendAndCallReceiverTokensReceivedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MockNativeSendAndCallReceiverTokensReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MockNativeSendAndCallReceiverTokensReceived represents a TokensReceived event raised by the MockNativeSendAndCallReceiver contract. +type MockNativeSendAndCallReceiverTokensReceived struct { + SourceBlockchainID [32]byte + OriginTokenTransferrerAddress common.Address + OriginSenderAddress common.Address + Amount *big.Int + Payload []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokensReceived is a free log retrieval operation binding the contract event 0x98f64f0ad4e0e2a42535fa15b05dc6e800e16e439c98143fefabb72b43bad53e. +// +// Solidity: event TokensReceived(bytes32 indexed sourceBlockchainID, address indexed originTokenTransferrerAddress, address indexed originSenderAddress, uint256 amount, bytes payload) +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverFilterer) FilterTokensReceived(opts *bind.FilterOpts, sourceBlockchainID [][32]byte, originTokenTransferrerAddress []common.Address, originSenderAddress []common.Address) (*MockNativeSendAndCallReceiverTokensReceivedIterator, error) { + + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var originTokenTransferrerAddressRule []interface{} + for _, originTokenTransferrerAddressItem := range originTokenTransferrerAddress { + originTokenTransferrerAddressRule = append(originTokenTransferrerAddressRule, originTokenTransferrerAddressItem) + } + var originSenderAddressRule []interface{} + for _, originSenderAddressItem := range originSenderAddress { + originSenderAddressRule = append(originSenderAddressRule, originSenderAddressItem) + } + + logs, sub, err := _MockNativeSendAndCallReceiver.contract.FilterLogs(opts, "TokensReceived", sourceBlockchainIDRule, originTokenTransferrerAddressRule, originSenderAddressRule) + if err != nil { + return nil, err + } + return &MockNativeSendAndCallReceiverTokensReceivedIterator{contract: _MockNativeSendAndCallReceiver.contract, event: "TokensReceived", logs: logs, sub: sub}, nil +} + +// WatchTokensReceived is a free log subscription operation binding the contract event 0x98f64f0ad4e0e2a42535fa15b05dc6e800e16e439c98143fefabb72b43bad53e. +// +// Solidity: event TokensReceived(bytes32 indexed sourceBlockchainID, address indexed originTokenTransferrerAddress, address indexed originSenderAddress, uint256 amount, bytes payload) +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverFilterer) WatchTokensReceived(opts *bind.WatchOpts, sink chan<- *MockNativeSendAndCallReceiverTokensReceived, sourceBlockchainID [][32]byte, originTokenTransferrerAddress []common.Address, originSenderAddress []common.Address) (event.Subscription, error) { + + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var originTokenTransferrerAddressRule []interface{} + for _, originTokenTransferrerAddressItem := range originTokenTransferrerAddress { + originTokenTransferrerAddressRule = append(originTokenTransferrerAddressRule, originTokenTransferrerAddressItem) + } + var originSenderAddressRule []interface{} + for _, originSenderAddressItem := range originSenderAddress { + originSenderAddressRule = append(originSenderAddressRule, originSenderAddressItem) + } + + logs, sub, err := _MockNativeSendAndCallReceiver.contract.WatchLogs(opts, "TokensReceived", sourceBlockchainIDRule, originTokenTransferrerAddressRule, originSenderAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MockNativeSendAndCallReceiverTokensReceived) + if err := _MockNativeSendAndCallReceiver.contract.UnpackLog(event, "TokensReceived", 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 +} + +// ParseTokensReceived is a log parse operation binding the contract event 0x98f64f0ad4e0e2a42535fa15b05dc6e800e16e439c98143fefabb72b43bad53e. +// +// Solidity: event TokensReceived(bytes32 indexed sourceBlockchainID, address indexed originTokenTransferrerAddress, address indexed originSenderAddress, uint256 amount, bytes payload) +func (_MockNativeSendAndCallReceiver *MockNativeSendAndCallReceiverFilterer) ParseTokensReceived(log types.Log) (*MockNativeSendAndCallReceiverTokensReceived, error) { + event := new(MockNativeSendAndCallReceiverTokensReceived) + if err := _MockNativeSendAndCallReceiver.contract.UnpackLog(event, "TokensReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/mocks/ExampleERC20/ExampleERC20.go b/abi-bindings/go/mocks/ExampleERC20/ExampleERC20.go new file mode 100644 index 000000000..d2da3080b --- /dev/null +++ b/abi-bindings/go/mocks/ExampleERC20/ExampleERC20.go @@ -0,0 +1,844 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package exampleerc20 + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ExampleERC20MetaData contains all meta data concerning the ExampleERC20 contract. +var ExampleERC20MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b506040518060400160405280600a81526020016926b7b1b5902a37b5b2b760b11b81525060405180604001604052806004815260200163045584d560e41b815250816003908161005f919061028b565b50600461006c828261028b565b50505061008b336b204fce5e3e2502611000000061009060201b60201c565b61036f565b6001600160a01b0382166100be5760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100c95f83836100cd565b5050565b6001600160a01b0383166100f7578060025f8282546100ec919061034a565b909155506101679050565b6001600160a01b0383165f90815260208190526040902054818110156101495760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016100b5565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216610183576002805482900390556101a1565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101e691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061021b57607f821691505b60208210810361023957634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561028657805f5260205f20601f840160051c810160208510156102645750805b601f840160051c820191505b81811015610283575f8155600101610270565b50505b505050565b81516001600160401b038111156102a4576102a46101f3565b6102b8816102b28454610207565b8461023f565b602080601f8311600181146102eb575f84156102d45750858301515b5f19600386901b1c1916600185901b178555610342565b5f85815260208120601f198616915b82811015610319578886015182559484019460019091019084016102fa565b508582101561033657878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b8082018082111561036957634e487b7160e01b5f52601160045260245ffd5b92915050565b6108eb8061037c5f395ff3fe608060405234801561000f575f80fd5b50600436106100cb575f3560e01c806342966c681161008857806395d89b411161006357806395d89b41146101a7578063a0712d68146101af578063a9059cbb146101c2578063dd62ed3e146101d5575f80fd5b806342966c681461015957806370a082311461016c57806379cc679014610194575f80fd5b806306fdde03146100cf578063095ea7b3146100ed57806318160ddd1461011057806323b872dd14610122578063313ce5671461013557806340c10f1914610144575b5f80fd5b6100d761020d565b6040516100e4919061072e565b60405180910390f35b6101006100fb366004610795565b61029d565b60405190151581526020016100e4565b6002545b6040519081526020016100e4565b6101006101303660046107bd565b6102b6565b604051601281526020016100e4565b610157610152366004610795565b6102d9565b005b6101576101673660046107f6565b610344565b61011461017a36600461080d565b6001600160a01b03165f9081526020819052604090205490565b6101576101a2366004610795565b610351565b6100d7610366565b6101576101bd3660046107f6565b610375565b6101006101d0366004610795565b6103d7565b6101146101e336600461082d565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b60606003805461021c9061085e565b80601f01602080910402602001604051908101604052809291908181526020018280546102489061085e565b80156102935780601f1061026a57610100808354040283529160200191610293565b820191905f5260205f20905b81548152906001019060200180831161027657829003601f168201915b5050505050905090565b5f336102aa8185856103e4565b60019150505b92915050565b5f336102c38582856103f6565b6102ce858585610471565b506001949350505050565b678ac7230489e800008111156103365760405162461bcd60e51b815260206004820152601f60248201527f4578616d706c6545524332303a206d6178206d696e742065786365656465640060448201526064015b60405180910390fd5b61034082826104ce565b5050565b61034e3382610502565b50565b61035c8233836103f6565b6103408282610502565b60606004805461021c9061085e565b678ac7230489e800008111156103cd5760405162461bcd60e51b815260206004820152601f60248201527f4578616d706c6545524332303a206d6178206d696e7420657863656564656400604482015260640161032d565b61034e33826104ce565b5f336102aa818585610471565b6103f18383836001610536565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811461046b578181101561045d57604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161032d565b61046b84848484035f610536565b50505050565b6001600160a01b03831661049a57604051634b637e8f60e11b81525f600482015260240161032d565b6001600160a01b0382166104c35760405163ec442f0560e01b81525f600482015260240161032d565b6103f1838383610608565b6001600160a01b0382166104f75760405163ec442f0560e01b81525f600482015260240161032d565b6103405f8383610608565b6001600160a01b03821661052b57604051634b637e8f60e11b81525f600482015260240161032d565b610340825f83610608565b6001600160a01b03841661055f5760405163e602df0560e01b81525f600482015260240161032d565b6001600160a01b03831661058857604051634a1406b160e11b81525f600482015260240161032d565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561046b57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105fa91815260200190565b60405180910390a350505050565b6001600160a01b038316610632578060025f8282546106279190610896565b909155506106a29050565b6001600160a01b0383165f90815260208190526040902054818110156106845760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161032d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166106be576002805482900390556106dc565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161072191815260200190565b60405180910390a3505050565b5f602080835283518060208501525f5b8181101561075a5785810183015185820160400152820161073e565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610790575f80fd5b919050565b5f80604083850312156107a6575f80fd5b6107af8361077a565b946020939093013593505050565b5f805f606084860312156107cf575f80fd5b6107d88461077a565b92506107e66020850161077a565b9150604084013590509250925092565b5f60208284031215610806575f80fd5b5035919050565b5f6020828403121561081d575f80fd5b6108268261077a565b9392505050565b5f806040838503121561083e575f80fd5b6108478361077a565b91506108556020840161077a565b90509250929050565b600181811c9082168061087257607f821691505b60208210810361089057634e487b7160e01b5f52602260045260245ffd5b50919050565b808201808211156102b057634e487b7160e01b5f52601160045260245ffdfea26469706673582212201302c474ec02cd179b13592e970a7684bfc5804d0ff12968c63674916e3bb4d864736f6c63430008190033", +} + +// ExampleERC20ABI is the input ABI used to generate the binding from. +// Deprecated: Use ExampleERC20MetaData.ABI instead. +var ExampleERC20ABI = ExampleERC20MetaData.ABI + +// ExampleERC20Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ExampleERC20MetaData.Bin instead. +var ExampleERC20Bin = ExampleERC20MetaData.Bin + +// DeployExampleERC20 deploys a new Ethereum contract, binding an instance of ExampleERC20 to it. +func DeployExampleERC20(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ExampleERC20, error) { + parsed, err := ExampleERC20MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ExampleERC20Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ExampleERC20{ExampleERC20Caller: ExampleERC20Caller{contract: contract}, ExampleERC20Transactor: ExampleERC20Transactor{contract: contract}, ExampleERC20Filterer: ExampleERC20Filterer{contract: contract}}, nil +} + +// ExampleERC20 is an auto generated Go binding around an Ethereum contract. +type ExampleERC20 struct { + ExampleERC20Caller // Read-only binding to the contract + ExampleERC20Transactor // Write-only binding to the contract + ExampleERC20Filterer // Log filterer for contract events +} + +// ExampleERC20Caller is an auto generated read-only Go binding around an Ethereum contract. +type ExampleERC20Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleERC20Transactor is an auto generated write-only Go binding around an Ethereum contract. +type ExampleERC20Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleERC20Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ExampleERC20Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleERC20Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ExampleERC20Session struct { + Contract *ExampleERC20 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleERC20CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ExampleERC20CallerSession struct { + Contract *ExampleERC20Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ExampleERC20TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ExampleERC20TransactorSession struct { + Contract *ExampleERC20Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleERC20Raw is an auto generated low-level Go binding around an Ethereum contract. +type ExampleERC20Raw struct { + Contract *ExampleERC20 // Generic contract binding to access the raw methods on +} + +// ExampleERC20CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ExampleERC20CallerRaw struct { + Contract *ExampleERC20Caller // Generic read-only contract binding to access the raw methods on +} + +// ExampleERC20TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ExampleERC20TransactorRaw struct { + Contract *ExampleERC20Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewExampleERC20 creates a new instance of ExampleERC20, bound to a specific deployed contract. +func NewExampleERC20(address common.Address, backend bind.ContractBackend) (*ExampleERC20, error) { + contract, err := bindExampleERC20(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ExampleERC20{ExampleERC20Caller: ExampleERC20Caller{contract: contract}, ExampleERC20Transactor: ExampleERC20Transactor{contract: contract}, ExampleERC20Filterer: ExampleERC20Filterer{contract: contract}}, nil +} + +// NewExampleERC20Caller creates a new read-only instance of ExampleERC20, bound to a specific deployed contract. +func NewExampleERC20Caller(address common.Address, caller bind.ContractCaller) (*ExampleERC20Caller, error) { + contract, err := bindExampleERC20(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ExampleERC20Caller{contract: contract}, nil +} + +// NewExampleERC20Transactor creates a new write-only instance of ExampleERC20, bound to a specific deployed contract. +func NewExampleERC20Transactor(address common.Address, transactor bind.ContractTransactor) (*ExampleERC20Transactor, error) { + contract, err := bindExampleERC20(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ExampleERC20Transactor{contract: contract}, nil +} + +// NewExampleERC20Filterer creates a new log filterer instance of ExampleERC20, bound to a specific deployed contract. +func NewExampleERC20Filterer(address common.Address, filterer bind.ContractFilterer) (*ExampleERC20Filterer, error) { + contract, err := bindExampleERC20(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ExampleERC20Filterer{contract: contract}, nil +} + +// bindExampleERC20 binds a generic wrapper to an already deployed contract. +func bindExampleERC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ExampleERC20MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleERC20 *ExampleERC20Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleERC20.Contract.ExampleERC20Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleERC20 *ExampleERC20Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleERC20.Contract.ExampleERC20Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleERC20 *ExampleERC20Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleERC20.Contract.ExampleERC20Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleERC20 *ExampleERC20CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleERC20.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleERC20 *ExampleERC20TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleERC20.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleERC20 *ExampleERC20TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleERC20.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ExampleERC20 *ExampleERC20Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _ExampleERC20.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ExampleERC20 *ExampleERC20Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ExampleERC20.Contract.Allowance(&_ExampleERC20.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ExampleERC20 *ExampleERC20CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ExampleERC20.Contract.Allowance(&_ExampleERC20.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ExampleERC20 *ExampleERC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _ExampleERC20.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ExampleERC20 *ExampleERC20Session) BalanceOf(account common.Address) (*big.Int, error) { + return _ExampleERC20.Contract.BalanceOf(&_ExampleERC20.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ExampleERC20 *ExampleERC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ExampleERC20.Contract.BalanceOf(&_ExampleERC20.CallOpts, account) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ExampleERC20 *ExampleERC20Caller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ExampleERC20.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ExampleERC20 *ExampleERC20Session) Decimals() (uint8, error) { + return _ExampleERC20.Contract.Decimals(&_ExampleERC20.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_ExampleERC20 *ExampleERC20CallerSession) Decimals() (uint8, error) { + return _ExampleERC20.Contract.Decimals(&_ExampleERC20.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ExampleERC20 *ExampleERC20Caller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ExampleERC20.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ExampleERC20 *ExampleERC20Session) Name() (string, error) { + return _ExampleERC20.Contract.Name(&_ExampleERC20.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_ExampleERC20 *ExampleERC20CallerSession) Name() (string, error) { + return _ExampleERC20.Contract.Name(&_ExampleERC20.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ExampleERC20 *ExampleERC20Caller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ExampleERC20.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ExampleERC20 *ExampleERC20Session) Symbol() (string, error) { + return _ExampleERC20.Contract.Symbol(&_ExampleERC20.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_ExampleERC20 *ExampleERC20CallerSession) Symbol() (string, error) { + return _ExampleERC20.Contract.Symbol(&_ExampleERC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ExampleERC20 *ExampleERC20Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ExampleERC20.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ExampleERC20 *ExampleERC20Session) TotalSupply() (*big.Int, error) { + return _ExampleERC20.Contract.TotalSupply(&_ExampleERC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ExampleERC20 *ExampleERC20CallerSession) TotalSupply() (*big.Int, error) { + return _ExampleERC20.Contract.TotalSupply(&_ExampleERC20.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20Transactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20Session) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Approve(&_ExampleERC20.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20TransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Approve(&_ExampleERC20.TransactOpts, spender, value) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 value) returns() +func (_ExampleERC20 *ExampleERC20Transactor) Burn(opts *bind.TransactOpts, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "burn", value) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 value) returns() +func (_ExampleERC20 *ExampleERC20Session) Burn(value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Burn(&_ExampleERC20.TransactOpts, value) +} + +// Burn is a paid mutator transaction binding the contract method 0x42966c68. +// +// Solidity: function burn(uint256 value) returns() +func (_ExampleERC20 *ExampleERC20TransactorSession) Burn(value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Burn(&_ExampleERC20.TransactOpts, value) +} + +// BurnFrom is a paid mutator transaction binding the contract method 0x79cc6790. +// +// Solidity: function burnFrom(address account, uint256 value) returns() +func (_ExampleERC20 *ExampleERC20Transactor) BurnFrom(opts *bind.TransactOpts, account common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "burnFrom", account, value) +} + +// BurnFrom is a paid mutator transaction binding the contract method 0x79cc6790. +// +// Solidity: function burnFrom(address account, uint256 value) returns() +func (_ExampleERC20 *ExampleERC20Session) BurnFrom(account common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.BurnFrom(&_ExampleERC20.TransactOpts, account, value) +} + +// BurnFrom is a paid mutator transaction binding the contract method 0x79cc6790. +// +// Solidity: function burnFrom(address account, uint256 value) returns() +func (_ExampleERC20 *ExampleERC20TransactorSession) BurnFrom(account common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.BurnFrom(&_ExampleERC20.TransactOpts, account, value) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20Transactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "mint", account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20Session) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint(&_ExampleERC20.TransactOpts, account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20TransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint(&_ExampleERC20.TransactOpts, account, amount) +} + +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. +// +// Solidity: function mint(uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20Transactor) Mint0(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "mint0", amount) +} + +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. +// +// Solidity: function mint(uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20Session) Mint0(amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint0(&_ExampleERC20.TransactOpts, amount) +} + +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. +// +// Solidity: function mint(uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20TransactorSession) Mint0(amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint0(&_ExampleERC20.TransactOpts, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20Transactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20Session) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Transfer(&_ExampleERC20.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20TransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Transfer(&_ExampleERC20.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20Session) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.TransferFrom(&_ExampleERC20.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_ExampleERC20 *ExampleERC20TransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.TransferFrom(&_ExampleERC20.TransactOpts, from, to, value) +} + +// ExampleERC20ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the ExampleERC20 contract. +type ExampleERC20ApprovalIterator struct { + Event *ExampleERC20Approval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ExampleERC20ApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ExampleERC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ExampleERC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ExampleERC20ApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ExampleERC20ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ExampleERC20Approval represents a Approval event raised by the ExampleERC20 contract. +type ExampleERC20Approval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ExampleERC20 *ExampleERC20Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ExampleERC20ApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ExampleERC20.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ExampleERC20ApprovalIterator{contract: _ExampleERC20.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ExampleERC20 *ExampleERC20Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ExampleERC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _ExampleERC20.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ExampleERC20Approval) + if err := _ExampleERC20.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_ExampleERC20 *ExampleERC20Filterer) ParseApproval(log types.Log) (*ExampleERC20Approval, error) { + event := new(ExampleERC20Approval) + if err := _ExampleERC20.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ExampleERC20TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ExampleERC20 contract. +type ExampleERC20TransferIterator struct { + Event *ExampleERC20Transfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ExampleERC20TransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ExampleERC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ExampleERC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ExampleERC20TransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ExampleERC20TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ExampleERC20Transfer represents a Transfer event raised by the ExampleERC20 contract. +type ExampleERC20Transfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ExampleERC20 *ExampleERC20Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ExampleERC20TransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ExampleERC20.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &ExampleERC20TransferIterator{contract: _ExampleERC20.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ExampleERC20 *ExampleERC20Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ExampleERC20Transfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _ExampleERC20.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ExampleERC20Transfer) + if err := _ExampleERC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_ExampleERC20 *ExampleERC20Filterer) ParseTransfer(log types.Log) (*ExampleERC20Transfer, error) { + event := new(ExampleERC20Transfer) + if err := _ExampleERC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/packer/packer.go b/abi-bindings/go/packer/packer.go new file mode 100644 index 000000000..cffbc654b --- /dev/null +++ b/abi-bindings/go/packer/packer.go @@ -0,0 +1,10 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package packer + +// Interface to be implemented manually by the user for all types that need to be packed +type ABIPacker interface { + Pack() ([]byte, error) + Unpack([]byte) error +} diff --git a/abi-bindings/go/packer/packer_test.go b/abi-bindings/go/packer/packer_test.go new file mode 100644 index 000000000..7925b8b01 --- /dev/null +++ b/abi-bindings/go/packer/packer_test.go @@ -0,0 +1,224 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package packer + +import ( + "fmt" + "go/ast" + "go/token" + "go/types" + "math/big" + "math/rand" + "reflect" + "testing" + + validatorsetsig "github.com/ava-labs/icm-services/abi-bindings/go/governance/ValidatorSetSig" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + teleporterregistry "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/registry/TeleporterRegistry" + + "github.com/stretchr/testify/require" + "golang.org/x/tools/go/packages" +) + +const interfaceName = "ABIPacker" + +// Paths below are relative to the current package. +const packagePath = "../..." +const currentPackagePath = "." + +var fs = token.NewFileSet() + +// These mapping of names to empty type instances is necessary to be able to bridge +// between the name of the type obtained by the AST parsing in findAllImplementers +// and the actual type that we can instantiate and populate using reflection. +// If a new type is added that implements ABIPacker, but is not added to this list, +// then the test will fail. +var packerTypes = map[string]ABIPacker{ + "ValidatorSetSigMessage": &validatorsetsig.ValidatorSetSigMessage{}, + "TeleporterMessage": &teleportermessenger.TeleporterMessage{}, + "ProtocolRegistryEntry": &teleporterregistry.ProtocolRegistryEntry{}, +} + +// findAllImplementers returns names of all structs that implement the ABIPacker interface +// in all packagees in the abi-bindings path. +func findAllImplementers(t *testing.T) []string { + cfg := &packages.Config{ + Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo, + Fset: fs, + } + interfacePkg, err := packages.Load(cfg, currentPackagePath) + require.NoError(t, err) + + var iface *types.Interface + // find the interface in the current package + for _, pkg := range interfacePkg { + for _, obj := range pkg.Types.Scope().Names() { + if obj == interfaceName { + ifaceObj := pkg.Types.Scope().Lookup(obj) + if ifaceObj == nil { + continue + } + if typ, ok := ifaceObj.Type().Underlying().(*types.Interface); ok { + iface = typ + break + } + } + } + } + require.NotNilf(t, iface, "Interface %s not found in package %s", interfaceName, currentPackagePath) + + pkgs, err := packages.Load(cfg, packagePath) + require.NoError(t, err) + + allImplementers := []string{} + + for _, pkg := range pkgs { + for _, file := range pkg.Syntax { + // Inspect types in the package + for _, decl := range file.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + for _, spec := range genDecl.Specs { + // We have a Type spec + typeSpec, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + // Find object matching the TypeSpec name in the package scope + obj := pkg.Types.Scope().Lookup(typeSpec.Name.Name) + if obj == nil { + continue + } + // Check if the typed object we have is a struct + _, ok = obj.Type().Underlying().(*types.Struct) + if !ok { + continue + } + // Lookup the object by name and cast it to types.Named + typeName := typeSpec.Name.Name + typeObj := pkg.Types.Scope().Lookup(typeName) + if typeObj == nil { + continue + } + named, ok := typeObj.Type().(*types.Named) + if !ok { + continue + } + // Finally check if the named struct we have implements the interface + if types.Implements(types.NewPointer(named), iface) { + allImplementers = append(allImplementers, named.Obj().Name()) + } + } + } + } + } + return allImplementers +} + +// This test checks for exhaustiveness of the ABIPacker interface implementations. +// It searches for all implementations of the ABIPacker interface in all of the packages in the abi-bindings path +// and then populates fields with random non-zero values. And then packs, unpacks and confirms that the output struct +// is equal to the initial randomly generated one. +// Note that the test itself doesn't rely on randomness. Any non-zero values will do. +func TestExhaustivePacking(t *testing.T) { + implementers := findAllImplementers(t) + for _, structName := range implementers { + packerType, ok := packerTypes[structName] + // If below fails it means that the developer implementer ABIPacker interface but forgot to add it + // to the packerTypes map. Without this check, we would only test structs that were added to the map + // which the developer would be unlikely to remember to update without this check. + require.True( + t, + ok, + fmt.Sprintf("Struct %s not found in packer_test.go packerTypes map. Add it to check for exhaustiveness", structName), + ) + + randomizedStruct, err := randomizeStruct(packerType) + require.NoError(t, err) + + v1 := randomizedStruct.(ABIPacker) + encoded, err := v1.Pack() + require.NoError(t, err) + v2 := reflect.New(reflect.TypeOf(v1).Elem()).Interface().(ABIPacker) + err = v2.Unpack(encoded) + require.NoError(t, err) + // v1 is a randomized struct instance and v2 is the one obtained by packing and unpacking v1 + // If they are not equal it means that the packing method wasn't updated and some fields in v2 + // are at their zero-value. + require.Equal(t, v1, v2) + } +} + +func randomizeStruct(packerStruct interface{}) (interface{}, error) { + v := reflect.ValueOf(packerStruct).Elem() + + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + err := randomizeField(field) + if err != nil { + return nil, err + } + } + return packerStruct, nil +} + +// randomizeField populates fields of structs with random values. +// It only supports types that are supported by abi-gen from Solidity types. +// The type conversion assumptions it makes are listed in `abi-bindings/README.md` +func randomizeField(field reflect.Value) error { + fieldType := field.Type() + switch fieldType.Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + field.SetInt(rand.Int63()) + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + field.SetUint(rand.Uint64()) + case reflect.Bool: + field.SetBool(rand.Intn(2) == 1) + case reflect.String: + field.SetString(randomString(rand.Intn(256))) + case reflect.Slice: + n := rand.Intn(256) + field.Set(reflect.MakeSlice(fieldType, n, n)) + for i := 0; i < field.Len(); i++ { + err := randomizeField(field.Index(i)) + if err != nil { + return fmt.Errorf("Error randomizing slice: %v", err) + } + } + case reflect.Struct: + randomizeStruct(field.Addr().Interface()) + case reflect.Array: + elemType := fieldType.Elem() + // arrays other than byte arrays get converted to slices by abigen + if elemType.Kind() != reflect.Uint8 { + return fmt.Errorf("Unsupported array type %s. Only byte arrays are supported.", elemType.Kind().String()) + } + for j := 0; j < field.Len(); j++ { + field.Index(j).SetUint(uint64(rand.Intn(256))) + } + + case reflect.Pointer: + if fieldType.Elem() == reflect.TypeOf(big.Int{}) { + newBigInt := big.NewInt(rand.Int63()) + field.Set(reflect.ValueOf(newBigInt)) + } else { + return fmt.Errorf("Unsupported pointer type %s", fieldType.Elem().String()) + } + default: + return fmt.Errorf("Unsupported type %s", fieldType.Kind().String()) + } + return nil +} + +// randomString generates a random string of the given length. +func randomString(length int) string { + const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + b := make([]byte, length) + for i := range b { + b[i] = charset[rand.Intn(len(charset))] + } + return string(b) +} diff --git a/abi-bindings/go/subnet-evm/INativeMinter/INativeMinter.go b/abi-bindings/go/subnet-evm/INativeMinter/INativeMinter.go new file mode 100644 index 000000000..a22d99aac --- /dev/null +++ b/abi-bindings/go/subnet-evm/INativeMinter/INativeMinter.go @@ -0,0 +1,634 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package inativeminter + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// INativeMinterMetaData contains all meta data concerning the INativeMinter contract. +var INativeMinterMetaData = &bind.MetaData{ + ABI: "[{\"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\":\"NativeCoinMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"role\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldRole\",\"type\":\"uint256\"}],\"name\":\"RoleSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintNativeCoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"readAllowList\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"role\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setNone\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// INativeMinterABI is the input ABI used to generate the binding from. +// Deprecated: Use INativeMinterMetaData.ABI instead. +var INativeMinterABI = INativeMinterMetaData.ABI + +// INativeMinter is an auto generated Go binding around an Ethereum contract. +type INativeMinter struct { + INativeMinterCaller // Read-only binding to the contract + INativeMinterTransactor // Write-only binding to the contract + INativeMinterFilterer // Log filterer for contract events +} + +// INativeMinterCaller is an auto generated read-only Go binding around an Ethereum contract. +type INativeMinterCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// INativeMinterTransactor is an auto generated write-only Go binding around an Ethereum contract. +type INativeMinterTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// INativeMinterFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type INativeMinterFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// INativeMinterSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type INativeMinterSession struct { + Contract *INativeMinter // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// INativeMinterCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type INativeMinterCallerSession struct { + Contract *INativeMinterCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// INativeMinterTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type INativeMinterTransactorSession struct { + Contract *INativeMinterTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// INativeMinterRaw is an auto generated low-level Go binding around an Ethereum contract. +type INativeMinterRaw struct { + Contract *INativeMinter // Generic contract binding to access the raw methods on +} + +// INativeMinterCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type INativeMinterCallerRaw struct { + Contract *INativeMinterCaller // Generic read-only contract binding to access the raw methods on +} + +// INativeMinterTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type INativeMinterTransactorRaw struct { + Contract *INativeMinterTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewINativeMinter creates a new instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinter(address common.Address, backend bind.ContractBackend) (*INativeMinter, error) { + contract, err := bindINativeMinter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &INativeMinter{INativeMinterCaller: INativeMinterCaller{contract: contract}, INativeMinterTransactor: INativeMinterTransactor{contract: contract}, INativeMinterFilterer: INativeMinterFilterer{contract: contract}}, nil +} + +// NewINativeMinterCaller creates a new read-only instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinterCaller(address common.Address, caller bind.ContractCaller) (*INativeMinterCaller, error) { + contract, err := bindINativeMinter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &INativeMinterCaller{contract: contract}, nil +} + +// NewINativeMinterTransactor creates a new write-only instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinterTransactor(address common.Address, transactor bind.ContractTransactor) (*INativeMinterTransactor, error) { + contract, err := bindINativeMinter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &INativeMinterTransactor{contract: contract}, nil +} + +// NewINativeMinterFilterer creates a new log filterer instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinterFilterer(address common.Address, filterer bind.ContractFilterer) (*INativeMinterFilterer, error) { + contract, err := bindINativeMinter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &INativeMinterFilterer{contract: contract}, nil +} + +// bindINativeMinter binds a generic wrapper to an already deployed contract. +func bindINativeMinter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := INativeMinterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_INativeMinter *INativeMinterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _INativeMinter.Contract.INativeMinterCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_INativeMinter *INativeMinterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _INativeMinter.Contract.INativeMinterTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_INativeMinter *INativeMinterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _INativeMinter.Contract.INativeMinterTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_INativeMinter *INativeMinterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _INativeMinter.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_INativeMinter *INativeMinterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _INativeMinter.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_INativeMinter *INativeMinterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _INativeMinter.Contract.contract.Transact(opts, method, params...) +} + +// ReadAllowList is a free data retrieval call binding the contract method 0xeb54dae1. +// +// Solidity: function readAllowList(address addr) view returns(uint256 role) +func (_INativeMinter *INativeMinterCaller) ReadAllowList(opts *bind.CallOpts, addr common.Address) (*big.Int, error) { + var out []interface{} + err := _INativeMinter.contract.Call(opts, &out, "readAllowList", addr) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ReadAllowList is a free data retrieval call binding the contract method 0xeb54dae1. +// +// Solidity: function readAllowList(address addr) view returns(uint256 role) +func (_INativeMinter *INativeMinterSession) ReadAllowList(addr common.Address) (*big.Int, error) { + return _INativeMinter.Contract.ReadAllowList(&_INativeMinter.CallOpts, addr) +} + +// ReadAllowList is a free data retrieval call binding the contract method 0xeb54dae1. +// +// Solidity: function readAllowList(address addr) view returns(uint256 role) +func (_INativeMinter *INativeMinterCallerSession) ReadAllowList(addr common.Address) (*big.Int, error) { + return _INativeMinter.Contract.ReadAllowList(&_INativeMinter.CallOpts, addr) +} + +// MintNativeCoin is a paid mutator transaction binding the contract method 0x4f5aaaba. +// +// Solidity: function mintNativeCoin(address addr, uint256 amount) returns() +func (_INativeMinter *INativeMinterTransactor) MintNativeCoin(opts *bind.TransactOpts, addr common.Address, amount *big.Int) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "mintNativeCoin", addr, amount) +} + +// MintNativeCoin is a paid mutator transaction binding the contract method 0x4f5aaaba. +// +// Solidity: function mintNativeCoin(address addr, uint256 amount) returns() +func (_INativeMinter *INativeMinterSession) MintNativeCoin(addr common.Address, amount *big.Int) (*types.Transaction, error) { + return _INativeMinter.Contract.MintNativeCoin(&_INativeMinter.TransactOpts, addr, amount) +} + +// MintNativeCoin is a paid mutator transaction binding the contract method 0x4f5aaaba. +// +// Solidity: function mintNativeCoin(address addr, uint256 amount) returns() +func (_INativeMinter *INativeMinterTransactorSession) MintNativeCoin(addr common.Address, amount *big.Int) (*types.Transaction, error) { + return _INativeMinter.Contract.MintNativeCoin(&_INativeMinter.TransactOpts, addr, amount) +} + +// SetAdmin is a paid mutator transaction binding the contract method 0x704b6c02. +// +// Solidity: function setAdmin(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetAdmin(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setAdmin", addr) +} + +// SetAdmin is a paid mutator transaction binding the contract method 0x704b6c02. +// +// Solidity: function setAdmin(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetAdmin(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetAdmin(&_INativeMinter.TransactOpts, addr) +} + +// SetAdmin is a paid mutator transaction binding the contract method 0x704b6c02. +// +// Solidity: function setAdmin(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetAdmin(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetAdmin(&_INativeMinter.TransactOpts, addr) +} + +// SetEnabled is a paid mutator transaction binding the contract method 0x0aaf7043. +// +// Solidity: function setEnabled(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetEnabled(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setEnabled", addr) +} + +// SetEnabled is a paid mutator transaction binding the contract method 0x0aaf7043. +// +// Solidity: function setEnabled(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetEnabled(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetEnabled(&_INativeMinter.TransactOpts, addr) +} + +// SetEnabled is a paid mutator transaction binding the contract method 0x0aaf7043. +// +// Solidity: function setEnabled(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetEnabled(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetEnabled(&_INativeMinter.TransactOpts, addr) +} + +// SetManager is a paid mutator transaction binding the contract method 0xd0ebdbe7. +// +// Solidity: function setManager(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetManager(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setManager", addr) +} + +// SetManager is a paid mutator transaction binding the contract method 0xd0ebdbe7. +// +// Solidity: function setManager(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetManager(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetManager(&_INativeMinter.TransactOpts, addr) +} + +// SetManager is a paid mutator transaction binding the contract method 0xd0ebdbe7. +// +// Solidity: function setManager(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetManager(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetManager(&_INativeMinter.TransactOpts, addr) +} + +// SetNone is a paid mutator transaction binding the contract method 0x8c6bfb3b. +// +// Solidity: function setNone(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetNone(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setNone", addr) +} + +// SetNone is a paid mutator transaction binding the contract method 0x8c6bfb3b. +// +// Solidity: function setNone(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetNone(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetNone(&_INativeMinter.TransactOpts, addr) +} + +// SetNone is a paid mutator transaction binding the contract method 0x8c6bfb3b. +// +// Solidity: function setNone(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetNone(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetNone(&_INativeMinter.TransactOpts, addr) +} + +// INativeMinterNativeCoinMintedIterator is returned from FilterNativeCoinMinted and is used to iterate over the raw logs and unpacked data for NativeCoinMinted events raised by the INativeMinter contract. +type INativeMinterNativeCoinMintedIterator struct { + Event *INativeMinterNativeCoinMinted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *INativeMinterNativeCoinMintedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(INativeMinterNativeCoinMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(INativeMinterNativeCoinMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *INativeMinterNativeCoinMintedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *INativeMinterNativeCoinMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// INativeMinterNativeCoinMinted represents a NativeCoinMinted event raised by the INativeMinter contract. +type INativeMinterNativeCoinMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNativeCoinMinted is a free log retrieval operation binding the contract event 0x400cd392f3d56fd10bb1dbd5839fdda8298208ddaa97b368faa053e1850930ee. +// +// Solidity: event NativeCoinMinted(address indexed sender, address indexed recipient, uint256 amount) +func (_INativeMinter *INativeMinterFilterer) FilterNativeCoinMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*INativeMinterNativeCoinMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _INativeMinter.contract.FilterLogs(opts, "NativeCoinMinted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &INativeMinterNativeCoinMintedIterator{contract: _INativeMinter.contract, event: "NativeCoinMinted", logs: logs, sub: sub}, nil +} + +// WatchNativeCoinMinted is a free log subscription operation binding the contract event 0x400cd392f3d56fd10bb1dbd5839fdda8298208ddaa97b368faa053e1850930ee. +// +// Solidity: event NativeCoinMinted(address indexed sender, address indexed recipient, uint256 amount) +func (_INativeMinter *INativeMinterFilterer) WatchNativeCoinMinted(opts *bind.WatchOpts, sink chan<- *INativeMinterNativeCoinMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _INativeMinter.contract.WatchLogs(opts, "NativeCoinMinted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(INativeMinterNativeCoinMinted) + if err := _INativeMinter.contract.UnpackLog(event, "NativeCoinMinted", 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 +} + +// ParseNativeCoinMinted is a log parse operation binding the contract event 0x400cd392f3d56fd10bb1dbd5839fdda8298208ddaa97b368faa053e1850930ee. +// +// Solidity: event NativeCoinMinted(address indexed sender, address indexed recipient, uint256 amount) +func (_INativeMinter *INativeMinterFilterer) ParseNativeCoinMinted(log types.Log) (*INativeMinterNativeCoinMinted, error) { + event := new(INativeMinterNativeCoinMinted) + if err := _INativeMinter.contract.UnpackLog(event, "NativeCoinMinted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// INativeMinterRoleSetIterator is returned from FilterRoleSet and is used to iterate over the raw logs and unpacked data for RoleSet events raised by the INativeMinter contract. +type INativeMinterRoleSetIterator struct { + Event *INativeMinterRoleSet // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *INativeMinterRoleSetIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(INativeMinterRoleSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(INativeMinterRoleSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *INativeMinterRoleSetIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *INativeMinterRoleSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// INativeMinterRoleSet represents a RoleSet event raised by the INativeMinter contract. +type INativeMinterRoleSet struct { + Role *big.Int + Account common.Address + Sender common.Address + OldRole *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleSet is a free log retrieval operation binding the contract event 0xcdb7ea01f00a414d78757bdb0f6391664ba3fedf987eed280927c1e7d695be3e. +// +// Solidity: event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole) +func (_INativeMinter *INativeMinterFilterer) FilterRoleSet(opts *bind.FilterOpts, role []*big.Int, account []common.Address, sender []common.Address) (*INativeMinterRoleSetIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _INativeMinter.contract.FilterLogs(opts, "RoleSet", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return &INativeMinterRoleSetIterator{contract: _INativeMinter.contract, event: "RoleSet", logs: logs, sub: sub}, nil +} + +// WatchRoleSet is a free log subscription operation binding the contract event 0xcdb7ea01f00a414d78757bdb0f6391664ba3fedf987eed280927c1e7d695be3e. +// +// Solidity: event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole) +func (_INativeMinter *INativeMinterFilterer) WatchRoleSet(opts *bind.WatchOpts, sink chan<- *INativeMinterRoleSet, role []*big.Int, account []common.Address, sender []common.Address) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _INativeMinter.contract.WatchLogs(opts, "RoleSet", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(INativeMinterRoleSet) + if err := _INativeMinter.contract.UnpackLog(event, "RoleSet", 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 +} + +// ParseRoleSet is a log parse operation binding the contract event 0xcdb7ea01f00a414d78757bdb0f6391664ba3fedf987eed280927c1e7d695be3e. +// +// Solidity: event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole) +func (_INativeMinter *INativeMinterFilterer) ParseRoleSet(log types.Log) (*INativeMinterRoleSet, error) { + event := new(INativeMinterRoleSet) + if err := _INativeMinter.contract.UnpackLog(event, "RoleSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/teleporter/TeleporterMessenger/TeleporterMessenger.go b/abi-bindings/go/teleporter/TeleporterMessenger/TeleporterMessenger.go new file mode 100644 index 000000000..08bf652b7 --- /dev/null +++ b/abi-bindings/go/teleporter/TeleporterMessenger/TeleporterMessenger.go @@ -0,0 +1,2131 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package teleportermessenger + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// TeleporterMessage is an auto generated low-level Go binding around an user-defined struct. +type TeleporterMessage struct { + MessageNonce *big.Int + OriginSenderAddress common.Address + DestinationBlockchainID [32]byte + DestinationAddress common.Address + RequiredGasLimit *big.Int + AllowedRelayerAddresses []common.Address + Receipts []TeleporterMessageReceipt + Message []byte +} + +// TeleporterMessageInput is an auto generated low-level Go binding around an user-defined struct. +type TeleporterMessageInput struct { + DestinationBlockchainID [32]byte + DestinationAddress common.Address + FeeInfo TeleporterFeeInfo + RequiredGasLimit *big.Int + AllowedRelayerAddresses []common.Address + Message []byte +} + +// TeleporterMessageReceipt is an auto generated low-level Go binding around an user-defined struct. +type TeleporterMessageReceipt struct { + ReceivedMessageNonce *big.Int + RelayerRewardAddress common.Address +} + +// TeleporterMessengerMetaData contains all meta data concerning the TeleporterMessenger contract. +var TeleporterMessengerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"updatedFeeInfo\",\"type\":\"tuple\"}],\"name\":\"AddFeeAmount\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"}],\"name\":\"BlockchainIDInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"MessageExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"structTeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"MessageExecutionFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"ReceiptReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"deliverer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRedeemer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"structTeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ReceiveCrossChainMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RelayerRewardsRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"structTeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"SendCrossChainMessage\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"WARP_MESSENGER\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"additionalFeeAmount\",\"type\":\"uint256\"}],\"name\":\"addFeeAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"calculateMessageID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAsset\",\"type\":\"address\"}],\"name\":\"checkRelayerRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getFeeInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getMessageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getNextMessageID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getReceiptAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"structTeleporterMessageReceipt\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getReceiptQueueSize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getRelayerRewardAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initializeBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"messageReceived\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"receiptQueues\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"first\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"last\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"name\":\"receiveCrossChainMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"receivedFailedMessageHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeAsset\",\"type\":\"address\"}],\"name\":\"redeemRelayerRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"structTeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"structTeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"retryMessageExecution\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"structTeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"structTeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"retrySendCrossChainMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"structTeleporterMessageInput\",\"name\":\"messageInput\",\"type\":\"tuple\"}],\"name\":\"sendCrossChainMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"messageIDs\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"}],\"name\":\"sendSpecifiedReceipts\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"sentMessageInfo\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600e575f80fd5b5060015f8190558055613142806100245f395ff3fe608060405234801561000f575f80fd5b5060043610610148575f3560e01c8063a8898181116100bf578063df20e8bc11610079578063df20e8bc14610331578063e69d606a14610344578063e6e67bd5146103ab578063ebc3b1ba146103e6578063ecc7042814610409578063fc2d619714610412575f80fd5b8063a8898181146102a9578063a9a85614146102bc578063b771b3bc146102cf578063c473eef8146102dd578063ccb5f80914610315578063d127dc9b14610328575f80fd5b8063399b77da11610110578063399b77da1461021257806362448850146102315780638245a1b014610244578063860a3b0614610257578063892bf412146102765780638ac0fd0414610296575f80fd5b80630af5b4ff1461014c57806322296c3a146101675780632bc8b0bf1461017c5780632ca40f551461018f5780632e27c223146101e7575b5f80fd5b610154610425565b6040519081526020015b60405180910390f35b61017a610175366004612138565b6104f3565b005b61015461018a366004612153565b6105e6565b6101d961019d366004612153565b600560209081525f9182526040918290208054835180850190945260018201546001600160a01b03168452600290910154918301919091529082565b60405161015e92919061216a565b6101fa6101f5366004612153565b610602565b6040516001600160a01b03909116815260200161015e565b610154610220366004612153565b5f9081526005602052604090205490565b61015461023f366004612191565b610689565b61017a6102523660046121de565b6106e2565b610154610265366004612153565b60066020525f908152604090205481565b61028961028436600461220f565b610885565b60405161015e919061222f565b61017a6102a436600461224f565b6108b6565b6101546102b7366004612284565b610aed565b6101546102ca3660046122f4565b610b2f565b6101fa6005600160991b0181565b6101546102eb366004612385565b6001600160a01b039182165f90815260096020908152604080832093909416825291909152205490565b61017a6103233660046123bc565b610dc1565b61015460025481565b61015461033f366004612153565b6111e3565b61038c610352366004612153565b5f90815260056020908152604091829020825180840190935260018101546001600160a01b03168084526002909101549290910182905291565b604080516001600160a01b03909316835260208301919091520161015e565b6103d16103b9366004612153565b60046020525f90815260409020805460019091015482565b6040805192835260208301919091520161015e565b6103f96103f4366004612153565b61122a565b604051901515815260200161015e565b61015460035481565b61017a6104203660046123e0565b61123f565b6002545f90806104ee576005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104969190612423565b9050806104be5760405162461bcd60e51b81526004016104b59061243a565b60405180910390fd5b600281905560405181907f1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104905f90a25b919050565b335f9081526009602090815260408083206001600160a01b0385168452909152902054806105745760405162461bcd60e51b815260206004820152602860248201527f54656c65706f727465724d657373656e6765723a206e6f2072657761726420746044820152676f2072656465656d60c01b60648201526084016104b5565b335f8181526009602090815260408083206001600160a01b03871680855290835281842093909355518481529192917f3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88910160405180910390a36105e26001600160a01b0383163383611494565b5050565b5f8181526004602052604081206105fc906114f8565b92915050565b5f8181526007602052604081205461066e5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f74604482015268081c9958d95a5d995960ba1b60648201526084016104b5565b505f908152600860205260409020546001600160a01b031690565b5f60015f54146106ab5760405162461bcd60e51b81526004016104b590612481565b60025f556106d86106bb836126b8565b83355f9081526004602052604090206106d39061150a565b611604565b60015f5592915050565b60015f54146107035760405162461bcd60e51b81526004016104b590612481565b60025f818155905461071b9060408401358435610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b0316845260029091015483830152908101919091528051919250906107825760405162461bcd60e51b81526004016104b590612757565b5f8360405160200161079491906129d6565b60408051601f19818403018152919052825181516020830120919250146107cd5760405162461bcd60e51b81526004016104b5906129e8565b8360400135837f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8868560200151604051610808929190612a31565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb9061083a908490600401612ab2565b6020604051808303815f875af1158015610856573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061087a9190612423565b505060015f55505050565b604080518082019091525f80825260208201525f8381526004602052604090206108af9083611837565b9392505050565b60015f54146108d75760405162461bcd60e51b81526004016104b590612481565b60025f5560018054146108fc5760405162461bcd60e51b81526004016104b590612ac4565b6002600155806109665760405162461bcd60e51b815260206004820152602f60248201527f54656c65706f727465724d657373656e6765723a207a65726f2061646469746960448201526e1bdb985b0819995948185b5bdd5b9d608a1b60648201526084016104b5565b6001600160a01b03821661098c5760405162461bcd60e51b81526004016104b590612b09565b5f838152600560205260409020546109b65760405162461bcd60e51b81526004016104b590612757565b5f838152600560205260409020600101546001600160a01b03838116911614610a475760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642066656560448201527f20617373657420636f6e7472616374206164647265737300000000000000000060648201526084016104b5565b5f610a5283836118f8565b5f85815260056020526040812060020180549293508392909190610a77908490612b71565b90915550505f8481526005602052604090819020905185917fc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e191610ad8916001019081546001600160a01b0316815260019190910154602082015260400190565b60405180910390a2505060018080555f555050565b6040805130602082015290810184905260608101839052608081018290525f9060a0016040516020818303038152906040528051906020012090509392505050565b5f60015f5414610b515760405162461bcd60e51b81526004016104b590612481565b60025f818155905490866001600160401b03811115610b7257610b726124c4565b604051908082528060200260200182016040528015610bb657816020015b604080518082019091525f8082526020820152815260200190600190039081610b905790505b509050865f5b81811015610d2e575f8a8a83818110610bd757610bd7612b84565b9050602002013590505f60075f8381526020019081526020015f20549050805f03610c535760405162461bcd60e51b815260206004820152602660248201527f54656c65706f727465724d657373656e6765723a2072656365697074206e6f7460448201526508199bdd5b9960d21b60648201526084016104b5565b610c5e8d8783610aed565b8214610cd25760405162461bcd60e51b815260206004820152603a60248201527f54656c65706f727465724d657373656e6765723a206d6573736167652049442060448201527f6e6f742066726f6d20736f7572636520626c6f636b636861696e00000000000060648201526084016104b5565b5f828152600860209081526040918290205482518084019093528383526001600160a01b03169082018190528651909190879086908110610d1557610d15612b84565b6020026020010181905250505050806001019050610bbc565b506040805160c0810182528b81525f6020820152610daf918101610d57368b90038b018b612b98565b81526020015f81526020018888808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052509385525050604080519283526020808401909152909201525083611604565b60015f559a9950505050505050505050565b6001805414610de25760405162461bcd60e51b81526004016104b590612ac4565b60026001556040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610e30573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e579190810190612c0e565b9150915080610eba5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642077617260448201526870206d65737361676560b81b60648201526084016104b5565b60208201516001600160a01b03163014610f315760405162461bcd60e51b815260206004820152603260248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206f726960448201527167696e2073656e646572206164647265737360701b60648201526084016104b5565b5f8260400151806020019051810190610f4a9190612da2565b90505f610f55610425565b905080826040015114610fc45760405162461bcd60e51b815260206004820152603160248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206465736044820152701d1a5b985d1a5bdb8818da185a5b881251607a1b60648201526084016104b5565b835182515f91610fd5918490610aed565b5f81815260076020526040902054909150156110495760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f727465724d657373656e6765723a206d65737361676520616c7260448201526c1958591e481c9958d95a5d9959609a1b60648201526084016104b5565b611057338460a00151611904565b6110b55760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20756e617574686f72697a6560448201526832103932b630bcb2b960b91b60648201526084016104b5565b6110c281845f0151611970565b6001600160a01b038616156110f8575f81815260086020526040902080546001600160a01b0319166001600160a01b0388161790555b60c0830151515f5b8181101561113b5761113384885f01518760c00151848151811061112657611126612b84565b60200260200101516119e0565b600101611100565b50604080518082018252855181526001600160a01b03891660208083019190915288515f90815260049091529190912061117491611b04565b336001600160a01b0316865f0151837f292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e348a886040516111b4929190612fb1565b60405180910390a460e084015151156111d5576111d582875f015186611b5e565b505060018055505050505050565b6002545f90806112055760405162461bcd60e51b81526004016104b59061243a565b5f60035460016112159190612b71565b9050611222828583610aed565b949350505050565b5f8181526007602052604081205415156105fc565b60018054146112605760405162461bcd60e51b81526004016104b590612ac4565b60026001819055545f906112779084908435610aed565b5f81815260066020526040902054909150806112a55760405162461bcd60e51b81526004016104b590612757565b80836040516020016112b791906129d6565b60405160208183030381529060405280519060200120146112ea5760405162461bcd60e51b81526004016104b5906129e8565b5f6112fb6080850160608601612138565b6001600160a01b03163b1161136f5760405162461bcd60e51b815260206004820152603460248201527f54656c65706f727465724d657373656e6765723a2064657374696e6174696f6e604482015273206164647265737320686173206e6f20636f646560601b60648201526084016104b5565b604051849083907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35f82815260066020908152604080832083905586916113be918701908701612138565b6113cb60e0870187612fd4565b6040516024016113de9493929190613016565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b17905290505f61142561141e6080870160608801612138565b5a84611c8d565b9050806114885760405162461bcd60e51b815260206004820152602b60248201527f54656c65706f727465724d657373656e6765723a20726574727920657865637560448201526a1d1a5bdb8819985a5b195960aa1b60648201526084016104b5565b50506001805550505050565b6040516001600160a01b038381166024830152604482018390526114f391859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ca4565b505050565b805460018201545f916105fc91613040565b60605f611520600561151b856114f8565b611d05565b9050805f0361156c57604080515f8082526020820190925290611564565b604080518082019091525f808252602082015281526020019060019003908161153e5790505b509392505050565b5f816001600160401b03811115611585576115856124c4565b6040519080825280602002602001820160405280156115c957816020015b604080518082019091525f80825260208201528152602001906001900390816115a35790505b5090505f5b82811015611564576115df85611d1a565b8282815181106115f1576115f1612b84565b60209081029190910101526001016115ce565b5f8061160e610425565b90505f60035f815461161f90613053565b91905081905590505f61163683875f015184610aed565b90505f604051806101000160405280848152602001336001600160a01b03168152602001885f0151815260200188602001516001600160a01b0316815260200188606001518152602001886080015181526020018781526020018860a0015181525090505f816040516020016116ac919061306b565b60405160208183030381529060405290505f808960400151602001511115611713576040890151516001600160a01b03166116f95760405162461bcd60e51b81526004016104b590612b09565b6040890151805160209091015161171091906118f8565b90505b6040805180820182528a820151516001600160a01b03908116825260208083018590528351808501855286518783012081528082018481525f8a815260058452869020915182555180516001830180546001600160a01b03191691909516179093559101516002909101558a51915190919086907f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8906117b6908890869061307d565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb906117e8908690600401612ab2565b6020604051808303815f875af1158015611804573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118289190612423565b50939998505050505050505050565b604080518082019091525f8082526020820152611853836114f8565b82106118ab5760405162461bcd60e51b815260206004820152602160248201527f5265636569707451756575653a20696e646578206f7574206f6620626f756e646044820152607360f81b60648201526084016104b5565b826002015f83855f01546118bf9190612b71565b815260208082019290925260409081015f20815180830190925280548252600101546001600160a01b0316918101919091529392505050565b5f6108af833384611de4565b5f81515f03611915575060016105fc565b81515f5b8181101561196657846001600160a01b031684828151811061193d5761193d612b84565b60200260200101516001600160a01b03160361195e576001925050506105fc565b600101611919565b505f949350505050565b805f036119cf5760405162461bcd60e51b815260206004820152602760248201527f54656c65706f727465724d657373656e6765723a207a65726f206d657373616760448201526665206e6f6e636560c81b60648201526084016104b5565b5f9182526007602052604090912055565b5f6119ef8484845f0151610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b031684526002909101548383015290810191909152805191925090611a45575050505050565b5f8281526005602090815260408083208381556001810180546001600160a01b03191690556002018390558382018051830151878401516001600160a01b0390811686526009855283862092515116855292528220805491929091611aab908490612b71565b9250508190555082602001516001600160a01b031684837fd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf578460200151604051611af5919061308f565b60405180910390a45050505050565b600182018054829160028501915f9182611b1d83613053565b9091555081526020808201929092526040015f2082518155910151600190910180546001600160a01b0319166001600160a01b039092169190911790555050565b80608001515a1015611bc05760405162461bcd60e51b815260206004820152602560248201527f54656c65706f727465724d657373656e6765723a20696e73756666696369656e604482015264742067617360d81b60648201526084016104b5565b80606001516001600160a01b03163b5f03611be0576114f3838383611f47565b602081015160e08201516040515f92611bfd9286926024016130af565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b179052606083015160808401519192505f91611c41919084611c8d565b905080611c5a57611c53858585611f47565b5050505050565b604051849086907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35050505050565b5f805f808451602086015f8989f195945050505050565b5f611cb86001600160a01b03841683611fbb565b905080515f14158015611cdc575080806020019051810190611cda91906130d8565b155b156114f357604051635274afe760e01b81526001600160a01b03841660048201526024016104b5565b5f818310611d1357816108af565b5090919050565b604080518082019091525f808252602082015281546001830154819003611d835760405162461bcd60e51b815260206004820152601960248201527f5265636569707451756575653a20656d7074792071756575650000000000000060448201526064016104b5565b5f8181526002840160208181526040808420815180830190925280548252600180820180546001600160a01b03811685870152888852959094529490556001600160a01b0319909216905590611dda908390612b71565b9093555090919050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa158015611e2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e4e9190612423565b9050611e656001600160a01b038616853086611fc8565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd9190612423565b9050818111611f335760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016104b5565b611f3d8282613040565b9695505050505050565b80604051602001611f58919061306b565b60408051601f1981840301815282825280516020918201205f878152600690925291902055829084907f4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c98590611fae90859061306b565b60405180910390a3505050565b60606108af83835f612007565b6040516001600160a01b0384811660248301528381166044830152606482018390526120019186918216906323b872dd906084016114c1565b50505050565b60608147101561202c5760405163cd78605960e01b81523060048201526024016104b5565b5f80856001600160a01b0316848660405161204791906130f1565b5f6040518083038185875af1925050503d805f8114612081576040519150601f19603f3d011682016040523d82523d5f602084013e612086565b606091505b5091509150611f3d8683836060826120a6576120a1826120ed565b6108af565b81511580156120bd57506001600160a01b0384163b155b156120e657604051639996b31560e01b81526001600160a01b03851660048201526024016104b5565b50806108af565b8051156120fd5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6001600160a01b0381168114612116575f80fd5b80356104ee81612119565b5f60208284031215612148575f80fd5b81356108af81612119565b5f60208284031215612163575f80fd5b5035919050565b828152606081016108af602083018480516001600160a01b03168252602090810151910152565b5f602082840312156121a1575f80fd5b81356001600160401b038111156121b6575f80fd5b820160e081850312156108af575f80fd5b5f61010082840312156121d8575f80fd5b50919050565b5f602082840312156121ee575f80fd5b81356001600160401b03811115612203575f80fd5b611222848285016121c7565b5f8060408385031215612220575f80fd5b50508035926020909101359150565b815181526020808301516001600160a01b031690820152604081016105fc565b5f805f60608486031215612261575f80fd5b83359250602084013561227381612119565b929592945050506040919091013590565b5f805f60608486031215612296575f80fd5b505081359360208301359350604090920135919050565b5f8083601f8401126122bd575f80fd5b5081356001600160401b038111156122d3575f80fd5b6020830191508360208260051b85010111156122ed575f80fd5b9250929050565b5f805f805f8086880360a081121561230a575f80fd5b8735965060208801356001600160401b0380821115612327575f80fd5b6123338b838c016122ad565b90985096508691506040603f198401121561234c575f80fd5b60408a01955060808a0135925080831115612365575f80fd5b505061237389828a016122ad565b979a9699509497509295939492505050565b5f8060408385031215612396575f80fd5b82356123a181612119565b915060208301356123b181612119565b809150509250929050565b5f80604083850312156123cd575f80fd5b823563ffffffff811681146123a1575f80fd5b5f80604083850312156123f1575f80fd5b8235915060208301356001600160401b0381111561240d575f80fd5b612419858286016121c7565b9150509250929050565b5f60208284031215612433575f80fd5b5051919050565b60208082526027908201527f54656c65706f727465724d657373656e6765723a207a65726f20626c6f636b636040820152661a185a5b88125160ca1b606082015260800190565b60208082526023908201527f5265656e7472616e63794775617264733a2073656e646572207265656e7472616040820152626e637960e81b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156124fa576124fa6124c4565b60405290565b60405160c081016001600160401b03811182821017156124fa576124fa6124c4565b60405161010081016001600160401b03811182821017156124fa576124fa6124c4565b604051601f8201601f191681016001600160401b038111828210171561256d5761256d6124c4565b604052919050565b5f60408284031215612585575f80fd5b61258d6124d8565b9050813561259a81612119565b808252506020820135602082015292915050565b5f6001600160401b038211156125c6576125c66124c4565b5060051b60200190565b5f82601f8301126125df575f80fd5b813560206125f46125ef836125ae565b612545565b8083825260208201915060208460051b870101935086841115612615575f80fd5b602086015b8481101561263a57803561262d81612119565b835291830191830161261a565b509695505050505050565b5f6001600160401b0382111561265d5761265d6124c4565b50601f01601f191660200190565b5f82601f83011261267a575f80fd5b81356126886125ef82612645565b81815284602083860101111561269c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60e082360312156126c8575f80fd5b6126d0612500565b823581526126e06020840161212d565b60208201526126f23660408501612575565b60408201526080830135606082015260a08301356001600160401b038082111561271a575f80fd5b612726368387016125d0565b608084015260c085013591508082111561273e575f80fd5b5061274b3682860161266b565b60a08301525092915050565b60208082526026908201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f7460408201526508199bdd5b9960d21b606082015260800190565b5f808335601e198436030181126127b2575f80fd5b83016020810192503590506001600160401b038111156127d0575f80fd5b8060051b36038213156122ed575f80fd5b8183525f60208085019450825f5b8581101561281d57813561280281612119565b6001600160a01b0316875295820195908201906001016127ef565b509495945050505050565b5f808335601e1984360301811261283d575f80fd5b83016020810192503590506001600160401b0381111561285b575f80fd5b8060061b36038213156122ed575f80fd5b8183525f60208085019450825f5b8581101561281d57813587528282013561289381612119565b6001600160a01b031687840152604096870196919091019060010161287a565b5f808335601e198436030181126128c8575f80fd5b83016020810192503590506001600160401b038111156128e6575f80fd5b8036038213156122ed575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f61010082358452602083013561293281612119565b6001600160a01b03166020850152604083810135908501526129566060840161212d565b6001600160a01b031660608501526080838101359085015261297b60a084018461279d565b8260a087015261298e83870182846127e1565b9250505061299f60c0840184612828565b85830360c08701526129b283828461286c565b925050506129c360e08401846128b3565b85830360e0870152611f3d8382846128f4565b602081525f6108af602083018461291c565b60208082526029908201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206d65736040820152680e6c2ceca40d0c2e6d60bb1b606082015260800190565b606081525f612a43606083018561291c565b90506108af602083018480516001600160a01b03168252602090810151910152565b5f5b83811015612a7f578181015183820152602001612a67565b50505f910152565b5f8151808452612a9e816020860160208601612a65565b601f01601f19169290920160200192915050565b602081525f6108af6020830184612a87565b60208082526025908201527f5265656e7472616e63794775617264733a207265636569766572207265656e7460408201526472616e637960d81b606082015260800190565b60208082526034908201527f54656c65706f727465724d657373656e6765723a207a65726f2066656520617360408201527373657420636f6e7472616374206164647265737360601b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105fc576105fc612b5d565b634e487b7160e01b5f52603260045260245ffd5b5f60408284031215612ba8575f80fd5b6108af8383612575565b80516104ee81612119565b5f82601f830112612bcc575f80fd5b8151612bda6125ef82612645565b818152846020838601011115612bee575f80fd5b611222826020830160208701612a65565b805180151581146104ee575f80fd5b5f8060408385031215612c1f575f80fd5b82516001600160401b0380821115612c35575f80fd5b9084019060608287031215612c48575f80fd5b604051606081018181108382111715612c6357612c636124c4565b604052825181526020830151612c7881612119565b6020820152604083015182811115612c8e575f80fd5b612c9a88828601612bbd565b6040830152509350612cb191505060208401612bff565b90509250929050565b5f82601f830112612cc9575f80fd5b81516020612cd96125ef836125ae565b8083825260208201915060208460051b870101935086841115612cfa575f80fd5b602086015b8481101561263a578051612d1281612119565b8352918301918301612cff565b5f82601f830112612d2e575f80fd5b81516020612d3e6125ef836125ae565b82815260069290921b84018101918181019086841115612d5c575f80fd5b8286015b8481101561263a5760408189031215612d77575f80fd5b612d7f6124d8565b8151815284820151612d9081612119565b81860152835291830191604001612d60565b5f60208284031215612db2575f80fd5b81516001600160401b0380821115612dc8575f80fd5b908301906101008286031215612ddc575f80fd5b612de4612522565b82518152612df460208401612bb2565b602082015260408301516040820152612e0f60608401612bb2565b60608201526080830151608082015260a083015182811115612e2f575f80fd5b612e3b87828601612cba565b60a08301525060c083015182811115612e52575f80fd5b612e5e87828601612d1f565b60c08301525060e083015182811115612e75575f80fd5b612e8187828601612bbd565b60e08301525095945050505050565b5f815180845260208085019450602084015f5b8381101561281d5781516001600160a01b031687529582019590820190600101612ea3565b5f815180845260208085019450602084015f5b8381101561281d57612f01878351805182526020908101516001600160a01b0316910152565b6040969096019590820190600101612edb565b5f6101008251845260018060a01b036020840151166020850152604083015160408501526060830151612f5260608601826001600160a01b03169052565b506080830151608085015260a08301518160a0860152612f7482860182612e90565b91505060c083015184820360c0860152612f8e8282612ec8565b91505060e083015184820360e0860152612fa88282612a87565b95945050505050565b6001600160a01b03831681526040602082018190525f9061122290830184612f14565b5f808335601e19843603018112612fe9575f80fd5b8301803591506001600160401b03821115613002575f80fd5b6020019150368190038213156122ed575f80fd5b8481526001600160a01b03841660208201526060604082018190525f90611f3d90830184866128f4565b818103818111156105fc576105fc612b5d565b5f6001820161306457613064612b5d565b5060010190565b602081525f6108af6020830184612f14565b606081525f612a436060830185612f14565b81516001600160a01b0316815260208083015190820152604081016105fc565b8381526001600160a01b03831660208201526060604082018190525f90612fa890830184612a87565b5f602082840312156130e8575f80fd5b6108af82612bff565b5f8251613102818460208701612a65565b919091019291505056fea2646970667358221220b9da062aeff8ff40d9d6ae3926de95e3f58630dfbe8975613e70ec0e8afd6b0764736f6c63430008190033", +} + +// TeleporterMessengerABI is the input ABI used to generate the binding from. +// Deprecated: Use TeleporterMessengerMetaData.ABI instead. +var TeleporterMessengerABI = TeleporterMessengerMetaData.ABI + +// TeleporterMessengerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TeleporterMessengerMetaData.Bin instead. +var TeleporterMessengerBin = TeleporterMessengerMetaData.Bin + +// DeployTeleporterMessenger deploys a new Ethereum contract, binding an instance of TeleporterMessenger to it. +func DeployTeleporterMessenger(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TeleporterMessenger, error) { + parsed, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TeleporterMessengerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TeleporterMessenger{TeleporterMessengerCaller: TeleporterMessengerCaller{contract: contract}, TeleporterMessengerTransactor: TeleporterMessengerTransactor{contract: contract}, TeleporterMessengerFilterer: TeleporterMessengerFilterer{contract: contract}}, nil +} + +// TeleporterMessenger is an auto generated Go binding around an Ethereum contract. +type TeleporterMessenger struct { + TeleporterMessengerCaller // Read-only binding to the contract + TeleporterMessengerTransactor // Write-only binding to the contract + TeleporterMessengerFilterer // Log filterer for contract events +} + +// TeleporterMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. +type TeleporterMessengerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TeleporterMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TeleporterMessengerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TeleporterMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TeleporterMessengerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TeleporterMessengerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TeleporterMessengerSession struct { + Contract *TeleporterMessenger // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TeleporterMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TeleporterMessengerCallerSession struct { + Contract *TeleporterMessengerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TeleporterMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TeleporterMessengerTransactorSession struct { + Contract *TeleporterMessengerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TeleporterMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. +type TeleporterMessengerRaw struct { + Contract *TeleporterMessenger // Generic contract binding to access the raw methods on +} + +// TeleporterMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TeleporterMessengerCallerRaw struct { + Contract *TeleporterMessengerCaller // Generic read-only contract binding to access the raw methods on +} + +// TeleporterMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TeleporterMessengerTransactorRaw struct { + Contract *TeleporterMessengerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTeleporterMessenger creates a new instance of TeleporterMessenger, bound to a specific deployed contract. +func NewTeleporterMessenger(address common.Address, backend bind.ContractBackend) (*TeleporterMessenger, error) { + contract, err := bindTeleporterMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TeleporterMessenger{TeleporterMessengerCaller: TeleporterMessengerCaller{contract: contract}, TeleporterMessengerTransactor: TeleporterMessengerTransactor{contract: contract}, TeleporterMessengerFilterer: TeleporterMessengerFilterer{contract: contract}}, nil +} + +// NewTeleporterMessengerCaller creates a new read-only instance of TeleporterMessenger, bound to a specific deployed contract. +func NewTeleporterMessengerCaller(address common.Address, caller bind.ContractCaller) (*TeleporterMessengerCaller, error) { + contract, err := bindTeleporterMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TeleporterMessengerCaller{contract: contract}, nil +} + +// NewTeleporterMessengerTransactor creates a new write-only instance of TeleporterMessenger, bound to a specific deployed contract. +func NewTeleporterMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*TeleporterMessengerTransactor, error) { + contract, err := bindTeleporterMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TeleporterMessengerTransactor{contract: contract}, nil +} + +// NewTeleporterMessengerFilterer creates a new log filterer instance of TeleporterMessenger, bound to a specific deployed contract. +func NewTeleporterMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*TeleporterMessengerFilterer, error) { + contract, err := bindTeleporterMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TeleporterMessengerFilterer{contract: contract}, nil +} + +// bindTeleporterMessenger binds a generic wrapper to an already deployed contract. +func bindTeleporterMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TeleporterMessenger *TeleporterMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TeleporterMessenger.Contract.TeleporterMessengerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TeleporterMessenger *TeleporterMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.TeleporterMessengerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TeleporterMessenger *TeleporterMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.TeleporterMessengerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TeleporterMessenger *TeleporterMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TeleporterMessenger.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TeleporterMessenger *TeleporterMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TeleporterMessenger *TeleporterMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.contract.Transact(opts, method, params...) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_TeleporterMessenger *TeleporterMessengerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_TeleporterMessenger *TeleporterMessengerSession) WARPMESSENGER() (common.Address, error) { + return _TeleporterMessenger.Contract.WARPMESSENGER(&_TeleporterMessenger.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) WARPMESSENGER() (common.Address, error) { + return _TeleporterMessenger.Contract.WARPMESSENGER(&_TeleporterMessenger.CallOpts) +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCaller) BlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "blockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerSession) BlockchainID() ([32]byte, error) { + return _TeleporterMessenger.Contract.BlockchainID(&_TeleporterMessenger.CallOpts) +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) BlockchainID() ([32]byte, error) { + return _TeleporterMessenger.Contract.BlockchainID(&_TeleporterMessenger.CallOpts) +} + +// CalculateMessageID is a free data retrieval call binding the contract method 0xa8898181. +// +// Solidity: function calculateMessageID(bytes32 sourceBlockchainID, bytes32 destinationBlockchainID, uint256 nonce) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCaller) CalculateMessageID(opts *bind.CallOpts, sourceBlockchainID [32]byte, destinationBlockchainID [32]byte, nonce *big.Int) ([32]byte, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "calculateMessageID", sourceBlockchainID, destinationBlockchainID, nonce) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// CalculateMessageID is a free data retrieval call binding the contract method 0xa8898181. +// +// Solidity: function calculateMessageID(bytes32 sourceBlockchainID, bytes32 destinationBlockchainID, uint256 nonce) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerSession) CalculateMessageID(sourceBlockchainID [32]byte, destinationBlockchainID [32]byte, nonce *big.Int) ([32]byte, error) { + return _TeleporterMessenger.Contract.CalculateMessageID(&_TeleporterMessenger.CallOpts, sourceBlockchainID, destinationBlockchainID, nonce) +} + +// CalculateMessageID is a free data retrieval call binding the contract method 0xa8898181. +// +// Solidity: function calculateMessageID(bytes32 sourceBlockchainID, bytes32 destinationBlockchainID, uint256 nonce) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) CalculateMessageID(sourceBlockchainID [32]byte, destinationBlockchainID [32]byte, nonce *big.Int) ([32]byte, error) { + return _TeleporterMessenger.Contract.CalculateMessageID(&_TeleporterMessenger.CallOpts, sourceBlockchainID, destinationBlockchainID, nonce) +} + +// CheckRelayerRewardAmount is a free data retrieval call binding the contract method 0xc473eef8. +// +// Solidity: function checkRelayerRewardAmount(address relayer, address feeAsset) view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerCaller) CheckRelayerRewardAmount(opts *bind.CallOpts, relayer common.Address, feeAsset common.Address) (*big.Int, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "checkRelayerRewardAmount", relayer, feeAsset) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CheckRelayerRewardAmount is a free data retrieval call binding the contract method 0xc473eef8. +// +// Solidity: function checkRelayerRewardAmount(address relayer, address feeAsset) view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerSession) CheckRelayerRewardAmount(relayer common.Address, feeAsset common.Address) (*big.Int, error) { + return _TeleporterMessenger.Contract.CheckRelayerRewardAmount(&_TeleporterMessenger.CallOpts, relayer, feeAsset) +} + +// CheckRelayerRewardAmount is a free data retrieval call binding the contract method 0xc473eef8. +// +// Solidity: function checkRelayerRewardAmount(address relayer, address feeAsset) view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) CheckRelayerRewardAmount(relayer common.Address, feeAsset common.Address) (*big.Int, error) { + return _TeleporterMessenger.Contract.CheckRelayerRewardAmount(&_TeleporterMessenger.CallOpts, relayer, feeAsset) +} + +// GetFeeInfo is a free data retrieval call binding the contract method 0xe69d606a. +// +// Solidity: function getFeeInfo(bytes32 messageID) view returns(address, uint256) +func (_TeleporterMessenger *TeleporterMessengerCaller) GetFeeInfo(opts *bind.CallOpts, messageID [32]byte) (common.Address, *big.Int, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "getFeeInfo", messageID) + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// GetFeeInfo is a free data retrieval call binding the contract method 0xe69d606a. +// +// Solidity: function getFeeInfo(bytes32 messageID) view returns(address, uint256) +func (_TeleporterMessenger *TeleporterMessengerSession) GetFeeInfo(messageID [32]byte) (common.Address, *big.Int, error) { + return _TeleporterMessenger.Contract.GetFeeInfo(&_TeleporterMessenger.CallOpts, messageID) +} + +// GetFeeInfo is a free data retrieval call binding the contract method 0xe69d606a. +// +// Solidity: function getFeeInfo(bytes32 messageID) view returns(address, uint256) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) GetFeeInfo(messageID [32]byte) (common.Address, *big.Int, error) { + return _TeleporterMessenger.Contract.GetFeeInfo(&_TeleporterMessenger.CallOpts, messageID) +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x399b77da. +// +// Solidity: function getMessageHash(bytes32 messageID) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCaller) GetMessageHash(opts *bind.CallOpts, messageID [32]byte) ([32]byte, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "getMessageHash", messageID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x399b77da. +// +// Solidity: function getMessageHash(bytes32 messageID) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerSession) GetMessageHash(messageID [32]byte) ([32]byte, error) { + return _TeleporterMessenger.Contract.GetMessageHash(&_TeleporterMessenger.CallOpts, messageID) +} + +// GetMessageHash is a free data retrieval call binding the contract method 0x399b77da. +// +// Solidity: function getMessageHash(bytes32 messageID) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) GetMessageHash(messageID [32]byte) ([32]byte, error) { + return _TeleporterMessenger.Contract.GetMessageHash(&_TeleporterMessenger.CallOpts, messageID) +} + +// GetNextMessageID is a free data retrieval call binding the contract method 0xdf20e8bc. +// +// Solidity: function getNextMessageID(bytes32 destinationBlockchainID) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCaller) GetNextMessageID(opts *bind.CallOpts, destinationBlockchainID [32]byte) ([32]byte, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "getNextMessageID", destinationBlockchainID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetNextMessageID is a free data retrieval call binding the contract method 0xdf20e8bc. +// +// Solidity: function getNextMessageID(bytes32 destinationBlockchainID) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerSession) GetNextMessageID(destinationBlockchainID [32]byte) ([32]byte, error) { + return _TeleporterMessenger.Contract.GetNextMessageID(&_TeleporterMessenger.CallOpts, destinationBlockchainID) +} + +// GetNextMessageID is a free data retrieval call binding the contract method 0xdf20e8bc. +// +// Solidity: function getNextMessageID(bytes32 destinationBlockchainID) view returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) GetNextMessageID(destinationBlockchainID [32]byte) ([32]byte, error) { + return _TeleporterMessenger.Contract.GetNextMessageID(&_TeleporterMessenger.CallOpts, destinationBlockchainID) +} + +// GetReceiptAtIndex is a free data retrieval call binding the contract method 0x892bf412. +// +// Solidity: function getReceiptAtIndex(bytes32 sourceBlockchainID, uint256 index) view returns((uint256,address)) +func (_TeleporterMessenger *TeleporterMessengerCaller) GetReceiptAtIndex(opts *bind.CallOpts, sourceBlockchainID [32]byte, index *big.Int) (TeleporterMessageReceipt, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "getReceiptAtIndex", sourceBlockchainID, index) + + if err != nil { + return *new(TeleporterMessageReceipt), err + } + + out0 := *abi.ConvertType(out[0], new(TeleporterMessageReceipt)).(*TeleporterMessageReceipt) + + return out0, err + +} + +// GetReceiptAtIndex is a free data retrieval call binding the contract method 0x892bf412. +// +// Solidity: function getReceiptAtIndex(bytes32 sourceBlockchainID, uint256 index) view returns((uint256,address)) +func (_TeleporterMessenger *TeleporterMessengerSession) GetReceiptAtIndex(sourceBlockchainID [32]byte, index *big.Int) (TeleporterMessageReceipt, error) { + return _TeleporterMessenger.Contract.GetReceiptAtIndex(&_TeleporterMessenger.CallOpts, sourceBlockchainID, index) +} + +// GetReceiptAtIndex is a free data retrieval call binding the contract method 0x892bf412. +// +// Solidity: function getReceiptAtIndex(bytes32 sourceBlockchainID, uint256 index) view returns((uint256,address)) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) GetReceiptAtIndex(sourceBlockchainID [32]byte, index *big.Int) (TeleporterMessageReceipt, error) { + return _TeleporterMessenger.Contract.GetReceiptAtIndex(&_TeleporterMessenger.CallOpts, sourceBlockchainID, index) +} + +// GetReceiptQueueSize is a free data retrieval call binding the contract method 0x2bc8b0bf. +// +// Solidity: function getReceiptQueueSize(bytes32 sourceBlockchainID) view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerCaller) GetReceiptQueueSize(opts *bind.CallOpts, sourceBlockchainID [32]byte) (*big.Int, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "getReceiptQueueSize", sourceBlockchainID) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetReceiptQueueSize is a free data retrieval call binding the contract method 0x2bc8b0bf. +// +// Solidity: function getReceiptQueueSize(bytes32 sourceBlockchainID) view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerSession) GetReceiptQueueSize(sourceBlockchainID [32]byte) (*big.Int, error) { + return _TeleporterMessenger.Contract.GetReceiptQueueSize(&_TeleporterMessenger.CallOpts, sourceBlockchainID) +} + +// GetReceiptQueueSize is a free data retrieval call binding the contract method 0x2bc8b0bf. +// +// Solidity: function getReceiptQueueSize(bytes32 sourceBlockchainID) view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) GetReceiptQueueSize(sourceBlockchainID [32]byte) (*big.Int, error) { + return _TeleporterMessenger.Contract.GetReceiptQueueSize(&_TeleporterMessenger.CallOpts, sourceBlockchainID) +} + +// GetRelayerRewardAddress is a free data retrieval call binding the contract method 0x2e27c223. +// +// Solidity: function getRelayerRewardAddress(bytes32 messageID) view returns(address) +func (_TeleporterMessenger *TeleporterMessengerCaller) GetRelayerRewardAddress(opts *bind.CallOpts, messageID [32]byte) (common.Address, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "getRelayerRewardAddress", messageID) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetRelayerRewardAddress is a free data retrieval call binding the contract method 0x2e27c223. +// +// Solidity: function getRelayerRewardAddress(bytes32 messageID) view returns(address) +func (_TeleporterMessenger *TeleporterMessengerSession) GetRelayerRewardAddress(messageID [32]byte) (common.Address, error) { + return _TeleporterMessenger.Contract.GetRelayerRewardAddress(&_TeleporterMessenger.CallOpts, messageID) +} + +// GetRelayerRewardAddress is a free data retrieval call binding the contract method 0x2e27c223. +// +// Solidity: function getRelayerRewardAddress(bytes32 messageID) view returns(address) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) GetRelayerRewardAddress(messageID [32]byte) (common.Address, error) { + return _TeleporterMessenger.Contract.GetRelayerRewardAddress(&_TeleporterMessenger.CallOpts, messageID) +} + +// MessageNonce is a free data retrieval call binding the contract method 0xecc70428. +// +// Solidity: function messageNonce() view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerCaller) MessageNonce(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "messageNonce") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MessageNonce is a free data retrieval call binding the contract method 0xecc70428. +// +// Solidity: function messageNonce() view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerSession) MessageNonce() (*big.Int, error) { + return _TeleporterMessenger.Contract.MessageNonce(&_TeleporterMessenger.CallOpts) +} + +// MessageNonce is a free data retrieval call binding the contract method 0xecc70428. +// +// Solidity: function messageNonce() view returns(uint256) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) MessageNonce() (*big.Int, error) { + return _TeleporterMessenger.Contract.MessageNonce(&_TeleporterMessenger.CallOpts) +} + +// MessageReceived is a free data retrieval call binding the contract method 0xebc3b1ba. +// +// Solidity: function messageReceived(bytes32 messageID) view returns(bool) +func (_TeleporterMessenger *TeleporterMessengerCaller) MessageReceived(opts *bind.CallOpts, messageID [32]byte) (bool, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "messageReceived", messageID) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// MessageReceived is a free data retrieval call binding the contract method 0xebc3b1ba. +// +// Solidity: function messageReceived(bytes32 messageID) view returns(bool) +func (_TeleporterMessenger *TeleporterMessengerSession) MessageReceived(messageID [32]byte) (bool, error) { + return _TeleporterMessenger.Contract.MessageReceived(&_TeleporterMessenger.CallOpts, messageID) +} + +// MessageReceived is a free data retrieval call binding the contract method 0xebc3b1ba. +// +// Solidity: function messageReceived(bytes32 messageID) view returns(bool) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) MessageReceived(messageID [32]byte) (bool, error) { + return _TeleporterMessenger.Contract.MessageReceived(&_TeleporterMessenger.CallOpts, messageID) +} + +// ReceiptQueues is a free data retrieval call binding the contract method 0xe6e67bd5. +// +// Solidity: function receiptQueues(bytes32 sourceBlockchainID) view returns(uint256 first, uint256 last) +func (_TeleporterMessenger *TeleporterMessengerCaller) ReceiptQueues(opts *bind.CallOpts, sourceBlockchainID [32]byte) (struct { + First *big.Int + Last *big.Int +}, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "receiptQueues", sourceBlockchainID) + + outstruct := new(struct { + First *big.Int + Last *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.First = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Last = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// ReceiptQueues is a free data retrieval call binding the contract method 0xe6e67bd5. +// +// Solidity: function receiptQueues(bytes32 sourceBlockchainID) view returns(uint256 first, uint256 last) +func (_TeleporterMessenger *TeleporterMessengerSession) ReceiptQueues(sourceBlockchainID [32]byte) (struct { + First *big.Int + Last *big.Int +}, error) { + return _TeleporterMessenger.Contract.ReceiptQueues(&_TeleporterMessenger.CallOpts, sourceBlockchainID) +} + +// ReceiptQueues is a free data retrieval call binding the contract method 0xe6e67bd5. +// +// Solidity: function receiptQueues(bytes32 sourceBlockchainID) view returns(uint256 first, uint256 last) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) ReceiptQueues(sourceBlockchainID [32]byte) (struct { + First *big.Int + Last *big.Int +}, error) { + return _TeleporterMessenger.Contract.ReceiptQueues(&_TeleporterMessenger.CallOpts, sourceBlockchainID) +} + +// ReceivedFailedMessageHashes is a free data retrieval call binding the contract method 0x860a3b06. +// +// Solidity: function receivedFailedMessageHashes(bytes32 messageID) view returns(bytes32 messageHash) +func (_TeleporterMessenger *TeleporterMessengerCaller) ReceivedFailedMessageHashes(opts *bind.CallOpts, messageID [32]byte) ([32]byte, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "receivedFailedMessageHashes", messageID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ReceivedFailedMessageHashes is a free data retrieval call binding the contract method 0x860a3b06. +// +// Solidity: function receivedFailedMessageHashes(bytes32 messageID) view returns(bytes32 messageHash) +func (_TeleporterMessenger *TeleporterMessengerSession) ReceivedFailedMessageHashes(messageID [32]byte) ([32]byte, error) { + return _TeleporterMessenger.Contract.ReceivedFailedMessageHashes(&_TeleporterMessenger.CallOpts, messageID) +} + +// ReceivedFailedMessageHashes is a free data retrieval call binding the contract method 0x860a3b06. +// +// Solidity: function receivedFailedMessageHashes(bytes32 messageID) view returns(bytes32 messageHash) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) ReceivedFailedMessageHashes(messageID [32]byte) ([32]byte, error) { + return _TeleporterMessenger.Contract.ReceivedFailedMessageHashes(&_TeleporterMessenger.CallOpts, messageID) +} + +// SentMessageInfo is a free data retrieval call binding the contract method 0x2ca40f55. +// +// Solidity: function sentMessageInfo(bytes32 messageID) view returns(bytes32 messageHash, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerCaller) SentMessageInfo(opts *bind.CallOpts, messageID [32]byte) (struct { + MessageHash [32]byte + FeeInfo TeleporterFeeInfo +}, error) { + var out []interface{} + err := _TeleporterMessenger.contract.Call(opts, &out, "sentMessageInfo", messageID) + + outstruct := new(struct { + MessageHash [32]byte + FeeInfo TeleporterFeeInfo + }) + if err != nil { + return *outstruct, err + } + + outstruct.MessageHash = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + outstruct.FeeInfo = *abi.ConvertType(out[1], new(TeleporterFeeInfo)).(*TeleporterFeeInfo) + + return *outstruct, err + +} + +// SentMessageInfo is a free data retrieval call binding the contract method 0x2ca40f55. +// +// Solidity: function sentMessageInfo(bytes32 messageID) view returns(bytes32 messageHash, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerSession) SentMessageInfo(messageID [32]byte) (struct { + MessageHash [32]byte + FeeInfo TeleporterFeeInfo +}, error) { + return _TeleporterMessenger.Contract.SentMessageInfo(&_TeleporterMessenger.CallOpts, messageID) +} + +// SentMessageInfo is a free data retrieval call binding the contract method 0x2ca40f55. +// +// Solidity: function sentMessageInfo(bytes32 messageID) view returns(bytes32 messageHash, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerCallerSession) SentMessageInfo(messageID [32]byte) (struct { + MessageHash [32]byte + FeeInfo TeleporterFeeInfo +}, error) { + return _TeleporterMessenger.Contract.SentMessageInfo(&_TeleporterMessenger.CallOpts, messageID) +} + +// AddFeeAmount is a paid mutator transaction binding the contract method 0x8ac0fd04. +// +// Solidity: function addFeeAmount(bytes32 messageID, address feeTokenAddress, uint256 additionalFeeAmount) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactor) AddFeeAmount(opts *bind.TransactOpts, messageID [32]byte, feeTokenAddress common.Address, additionalFeeAmount *big.Int) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "addFeeAmount", messageID, feeTokenAddress, additionalFeeAmount) +} + +// AddFeeAmount is a paid mutator transaction binding the contract method 0x8ac0fd04. +// +// Solidity: function addFeeAmount(bytes32 messageID, address feeTokenAddress, uint256 additionalFeeAmount) returns() +func (_TeleporterMessenger *TeleporterMessengerSession) AddFeeAmount(messageID [32]byte, feeTokenAddress common.Address, additionalFeeAmount *big.Int) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.AddFeeAmount(&_TeleporterMessenger.TransactOpts, messageID, feeTokenAddress, additionalFeeAmount) +} + +// AddFeeAmount is a paid mutator transaction binding the contract method 0x8ac0fd04. +// +// Solidity: function addFeeAmount(bytes32 messageID, address feeTokenAddress, uint256 additionalFeeAmount) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) AddFeeAmount(messageID [32]byte, feeTokenAddress common.Address, additionalFeeAmount *big.Int) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.AddFeeAmount(&_TeleporterMessenger.TransactOpts, messageID, feeTokenAddress, additionalFeeAmount) +} + +// InitializeBlockchainID is a paid mutator transaction binding the contract method 0x0af5b4ff. +// +// Solidity: function initializeBlockchainID() returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerTransactor) InitializeBlockchainID(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "initializeBlockchainID") +} + +// InitializeBlockchainID is a paid mutator transaction binding the contract method 0x0af5b4ff. +// +// Solidity: function initializeBlockchainID() returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerSession) InitializeBlockchainID() (*types.Transaction, error) { + return _TeleporterMessenger.Contract.InitializeBlockchainID(&_TeleporterMessenger.TransactOpts) +} + +// InitializeBlockchainID is a paid mutator transaction binding the contract method 0x0af5b4ff. +// +// Solidity: function initializeBlockchainID() returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) InitializeBlockchainID() (*types.Transaction, error) { + return _TeleporterMessenger.Contract.InitializeBlockchainID(&_TeleporterMessenger.TransactOpts) +} + +// ReceiveCrossChainMessage is a paid mutator transaction binding the contract method 0xccb5f809. +// +// Solidity: function receiveCrossChainMessage(uint32 messageIndex, address relayerRewardAddress) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactor) ReceiveCrossChainMessage(opts *bind.TransactOpts, messageIndex uint32, relayerRewardAddress common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "receiveCrossChainMessage", messageIndex, relayerRewardAddress) +} + +// ReceiveCrossChainMessage is a paid mutator transaction binding the contract method 0xccb5f809. +// +// Solidity: function receiveCrossChainMessage(uint32 messageIndex, address relayerRewardAddress) returns() +func (_TeleporterMessenger *TeleporterMessengerSession) ReceiveCrossChainMessage(messageIndex uint32, relayerRewardAddress common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.ReceiveCrossChainMessage(&_TeleporterMessenger.TransactOpts, messageIndex, relayerRewardAddress) +} + +// ReceiveCrossChainMessage is a paid mutator transaction binding the contract method 0xccb5f809. +// +// Solidity: function receiveCrossChainMessage(uint32 messageIndex, address relayerRewardAddress) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) ReceiveCrossChainMessage(messageIndex uint32, relayerRewardAddress common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.ReceiveCrossChainMessage(&_TeleporterMessenger.TransactOpts, messageIndex, relayerRewardAddress) +} + +// RedeemRelayerRewards is a paid mutator transaction binding the contract method 0x22296c3a. +// +// Solidity: function redeemRelayerRewards(address feeAsset) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactor) RedeemRelayerRewards(opts *bind.TransactOpts, feeAsset common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "redeemRelayerRewards", feeAsset) +} + +// RedeemRelayerRewards is a paid mutator transaction binding the contract method 0x22296c3a. +// +// Solidity: function redeemRelayerRewards(address feeAsset) returns() +func (_TeleporterMessenger *TeleporterMessengerSession) RedeemRelayerRewards(feeAsset common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.RedeemRelayerRewards(&_TeleporterMessenger.TransactOpts, feeAsset) +} + +// RedeemRelayerRewards is a paid mutator transaction binding the contract method 0x22296c3a. +// +// Solidity: function redeemRelayerRewards(address feeAsset) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) RedeemRelayerRewards(feeAsset common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.RedeemRelayerRewards(&_TeleporterMessenger.TransactOpts, feeAsset) +} + +// RetryMessageExecution is a paid mutator transaction binding the contract method 0xfc2d6197. +// +// Solidity: function retryMessageExecution(bytes32 sourceBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactor) RetryMessageExecution(opts *bind.TransactOpts, sourceBlockchainID [32]byte, message TeleporterMessage) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "retryMessageExecution", sourceBlockchainID, message) +} + +// RetryMessageExecution is a paid mutator transaction binding the contract method 0xfc2d6197. +// +// Solidity: function retryMessageExecution(bytes32 sourceBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) returns() +func (_TeleporterMessenger *TeleporterMessengerSession) RetryMessageExecution(sourceBlockchainID [32]byte, message TeleporterMessage) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.RetryMessageExecution(&_TeleporterMessenger.TransactOpts, sourceBlockchainID, message) +} + +// RetryMessageExecution is a paid mutator transaction binding the contract method 0xfc2d6197. +// +// Solidity: function retryMessageExecution(bytes32 sourceBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) RetryMessageExecution(sourceBlockchainID [32]byte, message TeleporterMessage) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.RetryMessageExecution(&_TeleporterMessenger.TransactOpts, sourceBlockchainID, message) +} + +// RetrySendCrossChainMessage is a paid mutator transaction binding the contract method 0x8245a1b0. +// +// Solidity: function retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactor) RetrySendCrossChainMessage(opts *bind.TransactOpts, message TeleporterMessage) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "retrySendCrossChainMessage", message) +} + +// RetrySendCrossChainMessage is a paid mutator transaction binding the contract method 0x8245a1b0. +// +// Solidity: function retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) returns() +func (_TeleporterMessenger *TeleporterMessengerSession) RetrySendCrossChainMessage(message TeleporterMessage) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.RetrySendCrossChainMessage(&_TeleporterMessenger.TransactOpts, message) +} + +// RetrySendCrossChainMessage is a paid mutator transaction binding the contract method 0x8245a1b0. +// +// Solidity: function retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) returns() +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) RetrySendCrossChainMessage(message TeleporterMessage) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.RetrySendCrossChainMessage(&_TeleporterMessenger.TransactOpts, message) +} + +// SendCrossChainMessage is a paid mutator transaction binding the contract method 0x62448850. +// +// Solidity: function sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes) messageInput) returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerTransactor) SendCrossChainMessage(opts *bind.TransactOpts, messageInput TeleporterMessageInput) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "sendCrossChainMessage", messageInput) +} + +// SendCrossChainMessage is a paid mutator transaction binding the contract method 0x62448850. +// +// Solidity: function sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes) messageInput) returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerSession) SendCrossChainMessage(messageInput TeleporterMessageInput) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.SendCrossChainMessage(&_TeleporterMessenger.TransactOpts, messageInput) +} + +// SendCrossChainMessage is a paid mutator transaction binding the contract method 0x62448850. +// +// Solidity: function sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes) messageInput) returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) SendCrossChainMessage(messageInput TeleporterMessageInput) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.SendCrossChainMessage(&_TeleporterMessenger.TransactOpts, messageInput) +} + +// SendSpecifiedReceipts is a paid mutator transaction binding the contract method 0xa9a85614. +// +// Solidity: function sendSpecifiedReceipts(bytes32 sourceBlockchainID, bytes32[] messageIDs, (address,uint256) feeInfo, address[] allowedRelayerAddresses) returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerTransactor) SendSpecifiedReceipts(opts *bind.TransactOpts, sourceBlockchainID [32]byte, messageIDs [][32]byte, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.contract.Transact(opts, "sendSpecifiedReceipts", sourceBlockchainID, messageIDs, feeInfo, allowedRelayerAddresses) +} + +// SendSpecifiedReceipts is a paid mutator transaction binding the contract method 0xa9a85614. +// +// Solidity: function sendSpecifiedReceipts(bytes32 sourceBlockchainID, bytes32[] messageIDs, (address,uint256) feeInfo, address[] allowedRelayerAddresses) returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerSession) SendSpecifiedReceipts(sourceBlockchainID [32]byte, messageIDs [][32]byte, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.SendSpecifiedReceipts(&_TeleporterMessenger.TransactOpts, sourceBlockchainID, messageIDs, feeInfo, allowedRelayerAddresses) +} + +// SendSpecifiedReceipts is a paid mutator transaction binding the contract method 0xa9a85614. +// +// Solidity: function sendSpecifiedReceipts(bytes32 sourceBlockchainID, bytes32[] messageIDs, (address,uint256) feeInfo, address[] allowedRelayerAddresses) returns(bytes32) +func (_TeleporterMessenger *TeleporterMessengerTransactorSession) SendSpecifiedReceipts(sourceBlockchainID [32]byte, messageIDs [][32]byte, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _TeleporterMessenger.Contract.SendSpecifiedReceipts(&_TeleporterMessenger.TransactOpts, sourceBlockchainID, messageIDs, feeInfo, allowedRelayerAddresses) +} + +// TeleporterMessengerAddFeeAmountIterator is returned from FilterAddFeeAmount and is used to iterate over the raw logs and unpacked data for AddFeeAmount events raised by the TeleporterMessenger contract. +type TeleporterMessengerAddFeeAmountIterator struct { + Event *TeleporterMessengerAddFeeAmount // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerAddFeeAmountIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerAddFeeAmount) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerAddFeeAmount) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerAddFeeAmountIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerAddFeeAmountIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerAddFeeAmount represents a AddFeeAmount event raised by the TeleporterMessenger contract. +type TeleporterMessengerAddFeeAmount struct { + MessageID [32]byte + UpdatedFeeInfo TeleporterFeeInfo + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddFeeAmount is a free log retrieval operation binding the contract event 0xc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e1. +// +// Solidity: event AddFeeAmount(bytes32 indexed messageID, (address,uint256) updatedFeeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterAddFeeAmount(opts *bind.FilterOpts, messageID [][32]byte) (*TeleporterMessengerAddFeeAmountIterator, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "AddFeeAmount", messageIDRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerAddFeeAmountIterator{contract: _TeleporterMessenger.contract, event: "AddFeeAmount", logs: logs, sub: sub}, nil +} + +// WatchAddFeeAmount is a free log subscription operation binding the contract event 0xc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e1. +// +// Solidity: event AddFeeAmount(bytes32 indexed messageID, (address,uint256) updatedFeeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchAddFeeAmount(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerAddFeeAmount, messageID [][32]byte) (event.Subscription, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "AddFeeAmount", messageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerAddFeeAmount) + if err := _TeleporterMessenger.contract.UnpackLog(event, "AddFeeAmount", 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 +} + +// ParseAddFeeAmount is a log parse operation binding the contract event 0xc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e1. +// +// Solidity: event AddFeeAmount(bytes32 indexed messageID, (address,uint256) updatedFeeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseAddFeeAmount(log types.Log) (*TeleporterMessengerAddFeeAmount, error) { + event := new(TeleporterMessengerAddFeeAmount) + if err := _TeleporterMessenger.contract.UnpackLog(event, "AddFeeAmount", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterMessengerBlockchainIDInitializedIterator is returned from FilterBlockchainIDInitialized and is used to iterate over the raw logs and unpacked data for BlockchainIDInitialized events raised by the TeleporterMessenger contract. +type TeleporterMessengerBlockchainIDInitializedIterator struct { + Event *TeleporterMessengerBlockchainIDInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerBlockchainIDInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerBlockchainIDInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerBlockchainIDInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerBlockchainIDInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerBlockchainIDInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerBlockchainIDInitialized represents a BlockchainIDInitialized event raised by the TeleporterMessenger contract. +type TeleporterMessengerBlockchainIDInitialized struct { + BlockchainID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockchainIDInitialized is a free log retrieval operation binding the contract event 0x1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104. +// +// Solidity: event BlockchainIDInitialized(bytes32 indexed blockchainID) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterBlockchainIDInitialized(opts *bind.FilterOpts, blockchainID [][32]byte) (*TeleporterMessengerBlockchainIDInitializedIterator, error) { + + var blockchainIDRule []interface{} + for _, blockchainIDItem := range blockchainID { + blockchainIDRule = append(blockchainIDRule, blockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "BlockchainIDInitialized", blockchainIDRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerBlockchainIDInitializedIterator{contract: _TeleporterMessenger.contract, event: "BlockchainIDInitialized", logs: logs, sub: sub}, nil +} + +// WatchBlockchainIDInitialized is a free log subscription operation binding the contract event 0x1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104. +// +// Solidity: event BlockchainIDInitialized(bytes32 indexed blockchainID) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchBlockchainIDInitialized(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerBlockchainIDInitialized, blockchainID [][32]byte) (event.Subscription, error) { + + var blockchainIDRule []interface{} + for _, blockchainIDItem := range blockchainID { + blockchainIDRule = append(blockchainIDRule, blockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "BlockchainIDInitialized", blockchainIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerBlockchainIDInitialized) + if err := _TeleporterMessenger.contract.UnpackLog(event, "BlockchainIDInitialized", 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 +} + +// ParseBlockchainIDInitialized is a log parse operation binding the contract event 0x1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104. +// +// Solidity: event BlockchainIDInitialized(bytes32 indexed blockchainID) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseBlockchainIDInitialized(log types.Log) (*TeleporterMessengerBlockchainIDInitialized, error) { + event := new(TeleporterMessengerBlockchainIDInitialized) + if err := _TeleporterMessenger.contract.UnpackLog(event, "BlockchainIDInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterMessengerMessageExecutedIterator is returned from FilterMessageExecuted and is used to iterate over the raw logs and unpacked data for MessageExecuted events raised by the TeleporterMessenger contract. +type TeleporterMessengerMessageExecutedIterator struct { + Event *TeleporterMessengerMessageExecuted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerMessageExecutedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerMessageExecuted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerMessageExecuted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerMessageExecutedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerMessageExecutedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerMessageExecuted represents a MessageExecuted event raised by the TeleporterMessenger contract. +type TeleporterMessengerMessageExecuted struct { + MessageID [32]byte + SourceBlockchainID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMessageExecuted is a free log retrieval operation binding the contract event 0x34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c. +// +// Solidity: event MessageExecuted(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterMessageExecuted(opts *bind.FilterOpts, messageID [][32]byte, sourceBlockchainID [][32]byte) (*TeleporterMessengerMessageExecutedIterator, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "MessageExecuted", messageIDRule, sourceBlockchainIDRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerMessageExecutedIterator{contract: _TeleporterMessenger.contract, event: "MessageExecuted", logs: logs, sub: sub}, nil +} + +// WatchMessageExecuted is a free log subscription operation binding the contract event 0x34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c. +// +// Solidity: event MessageExecuted(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchMessageExecuted(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerMessageExecuted, messageID [][32]byte, sourceBlockchainID [][32]byte) (event.Subscription, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "MessageExecuted", messageIDRule, sourceBlockchainIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerMessageExecuted) + if err := _TeleporterMessenger.contract.UnpackLog(event, "MessageExecuted", 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 +} + +// ParseMessageExecuted is a log parse operation binding the contract event 0x34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c. +// +// Solidity: event MessageExecuted(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseMessageExecuted(log types.Log) (*TeleporterMessengerMessageExecuted, error) { + event := new(TeleporterMessengerMessageExecuted) + if err := _TeleporterMessenger.contract.UnpackLog(event, "MessageExecuted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterMessengerMessageExecutionFailedIterator is returned from FilterMessageExecutionFailed and is used to iterate over the raw logs and unpacked data for MessageExecutionFailed events raised by the TeleporterMessenger contract. +type TeleporterMessengerMessageExecutionFailedIterator struct { + Event *TeleporterMessengerMessageExecutionFailed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerMessageExecutionFailedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerMessageExecutionFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerMessageExecutionFailed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerMessageExecutionFailedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerMessageExecutionFailedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerMessageExecutionFailed represents a MessageExecutionFailed event raised by the TeleporterMessenger contract. +type TeleporterMessengerMessageExecutionFailed struct { + MessageID [32]byte + SourceBlockchainID [32]byte + Message TeleporterMessage + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMessageExecutionFailed is a free log retrieval operation binding the contract event 0x4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c985. +// +// Solidity: event MessageExecutionFailed(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterMessageExecutionFailed(opts *bind.FilterOpts, messageID [][32]byte, sourceBlockchainID [][32]byte) (*TeleporterMessengerMessageExecutionFailedIterator, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "MessageExecutionFailed", messageIDRule, sourceBlockchainIDRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerMessageExecutionFailedIterator{contract: _TeleporterMessenger.contract, event: "MessageExecutionFailed", logs: logs, sub: sub}, nil +} + +// WatchMessageExecutionFailed is a free log subscription operation binding the contract event 0x4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c985. +// +// Solidity: event MessageExecutionFailed(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchMessageExecutionFailed(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerMessageExecutionFailed, messageID [][32]byte, sourceBlockchainID [][32]byte) (event.Subscription, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "MessageExecutionFailed", messageIDRule, sourceBlockchainIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerMessageExecutionFailed) + if err := _TeleporterMessenger.contract.UnpackLog(event, "MessageExecutionFailed", 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 +} + +// ParseMessageExecutionFailed is a log parse operation binding the contract event 0x4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c985. +// +// Solidity: event MessageExecutionFailed(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseMessageExecutionFailed(log types.Log) (*TeleporterMessengerMessageExecutionFailed, error) { + event := new(TeleporterMessengerMessageExecutionFailed) + if err := _TeleporterMessenger.contract.UnpackLog(event, "MessageExecutionFailed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterMessengerReceiptReceivedIterator is returned from FilterReceiptReceived and is used to iterate over the raw logs and unpacked data for ReceiptReceived events raised by the TeleporterMessenger contract. +type TeleporterMessengerReceiptReceivedIterator struct { + Event *TeleporterMessengerReceiptReceived // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerReceiptReceivedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerReceiptReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerReceiptReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerReceiptReceivedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerReceiptReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerReceiptReceived represents a ReceiptReceived event raised by the TeleporterMessenger contract. +type TeleporterMessengerReceiptReceived struct { + MessageID [32]byte + DestinationBlockchainID [32]byte + RelayerRewardAddress common.Address + FeeInfo TeleporterFeeInfo + Raw types.Log // Blockchain specific contextual infos +} + +// FilterReceiptReceived is a free log retrieval operation binding the contract event 0xd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf57. +// +// Solidity: event ReceiptReceived(bytes32 indexed messageID, bytes32 indexed destinationBlockchainID, address indexed relayerRewardAddress, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterReceiptReceived(opts *bind.FilterOpts, messageID [][32]byte, destinationBlockchainID [][32]byte, relayerRewardAddress []common.Address) (*TeleporterMessengerReceiptReceivedIterator, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var destinationBlockchainIDRule []interface{} + for _, destinationBlockchainIDItem := range destinationBlockchainID { + destinationBlockchainIDRule = append(destinationBlockchainIDRule, destinationBlockchainIDItem) + } + var relayerRewardAddressRule []interface{} + for _, relayerRewardAddressItem := range relayerRewardAddress { + relayerRewardAddressRule = append(relayerRewardAddressRule, relayerRewardAddressItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "ReceiptReceived", messageIDRule, destinationBlockchainIDRule, relayerRewardAddressRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerReceiptReceivedIterator{contract: _TeleporterMessenger.contract, event: "ReceiptReceived", logs: logs, sub: sub}, nil +} + +// WatchReceiptReceived is a free log subscription operation binding the contract event 0xd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf57. +// +// Solidity: event ReceiptReceived(bytes32 indexed messageID, bytes32 indexed destinationBlockchainID, address indexed relayerRewardAddress, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchReceiptReceived(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerReceiptReceived, messageID [][32]byte, destinationBlockchainID [][32]byte, relayerRewardAddress []common.Address) (event.Subscription, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var destinationBlockchainIDRule []interface{} + for _, destinationBlockchainIDItem := range destinationBlockchainID { + destinationBlockchainIDRule = append(destinationBlockchainIDRule, destinationBlockchainIDItem) + } + var relayerRewardAddressRule []interface{} + for _, relayerRewardAddressItem := range relayerRewardAddress { + relayerRewardAddressRule = append(relayerRewardAddressRule, relayerRewardAddressItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "ReceiptReceived", messageIDRule, destinationBlockchainIDRule, relayerRewardAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerReceiptReceived) + if err := _TeleporterMessenger.contract.UnpackLog(event, "ReceiptReceived", 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 +} + +// ParseReceiptReceived is a log parse operation binding the contract event 0xd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf57. +// +// Solidity: event ReceiptReceived(bytes32 indexed messageID, bytes32 indexed destinationBlockchainID, address indexed relayerRewardAddress, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseReceiptReceived(log types.Log) (*TeleporterMessengerReceiptReceived, error) { + event := new(TeleporterMessengerReceiptReceived) + if err := _TeleporterMessenger.contract.UnpackLog(event, "ReceiptReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterMessengerReceiveCrossChainMessageIterator is returned from FilterReceiveCrossChainMessage and is used to iterate over the raw logs and unpacked data for ReceiveCrossChainMessage events raised by the TeleporterMessenger contract. +type TeleporterMessengerReceiveCrossChainMessageIterator struct { + Event *TeleporterMessengerReceiveCrossChainMessage // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerReceiveCrossChainMessageIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerReceiveCrossChainMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerReceiveCrossChainMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerReceiveCrossChainMessageIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerReceiveCrossChainMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerReceiveCrossChainMessage represents a ReceiveCrossChainMessage event raised by the TeleporterMessenger contract. +type TeleporterMessengerReceiveCrossChainMessage struct { + MessageID [32]byte + SourceBlockchainID [32]byte + Deliverer common.Address + RewardRedeemer common.Address + Message TeleporterMessage + Raw types.Log // Blockchain specific contextual infos +} + +// FilterReceiveCrossChainMessage is a free log retrieval operation binding the contract event 0x292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e34. +// +// Solidity: event ReceiveCrossChainMessage(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, address indexed deliverer, address rewardRedeemer, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterReceiveCrossChainMessage(opts *bind.FilterOpts, messageID [][32]byte, sourceBlockchainID [][32]byte, deliverer []common.Address) (*TeleporterMessengerReceiveCrossChainMessageIterator, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var delivererRule []interface{} + for _, delivererItem := range deliverer { + delivererRule = append(delivererRule, delivererItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "ReceiveCrossChainMessage", messageIDRule, sourceBlockchainIDRule, delivererRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerReceiveCrossChainMessageIterator{contract: _TeleporterMessenger.contract, event: "ReceiveCrossChainMessage", logs: logs, sub: sub}, nil +} + +// WatchReceiveCrossChainMessage is a free log subscription operation binding the contract event 0x292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e34. +// +// Solidity: event ReceiveCrossChainMessage(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, address indexed deliverer, address rewardRedeemer, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchReceiveCrossChainMessage(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerReceiveCrossChainMessage, messageID [][32]byte, sourceBlockchainID [][32]byte, deliverer []common.Address) (event.Subscription, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var delivererRule []interface{} + for _, delivererItem := range deliverer { + delivererRule = append(delivererRule, delivererItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "ReceiveCrossChainMessage", messageIDRule, sourceBlockchainIDRule, delivererRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerReceiveCrossChainMessage) + if err := _TeleporterMessenger.contract.UnpackLog(event, "ReceiveCrossChainMessage", 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 +} + +// ParseReceiveCrossChainMessage is a log parse operation binding the contract event 0x292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e34. +// +// Solidity: event ReceiveCrossChainMessage(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, address indexed deliverer, address rewardRedeemer, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseReceiveCrossChainMessage(log types.Log) (*TeleporterMessengerReceiveCrossChainMessage, error) { + event := new(TeleporterMessengerReceiveCrossChainMessage) + if err := _TeleporterMessenger.contract.UnpackLog(event, "ReceiveCrossChainMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterMessengerRelayerRewardsRedeemedIterator is returned from FilterRelayerRewardsRedeemed and is used to iterate over the raw logs and unpacked data for RelayerRewardsRedeemed events raised by the TeleporterMessenger contract. +type TeleporterMessengerRelayerRewardsRedeemedIterator struct { + Event *TeleporterMessengerRelayerRewardsRedeemed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerRelayerRewardsRedeemedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerRelayerRewardsRedeemed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerRelayerRewardsRedeemed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerRelayerRewardsRedeemedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerRelayerRewardsRedeemedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerRelayerRewardsRedeemed represents a RelayerRewardsRedeemed event raised by the TeleporterMessenger contract. +type TeleporterMessengerRelayerRewardsRedeemed struct { + Redeemer common.Address + Asset common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRelayerRewardsRedeemed is a free log retrieval operation binding the contract event 0x3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88. +// +// Solidity: event RelayerRewardsRedeemed(address indexed redeemer, address indexed asset, uint256 amount) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterRelayerRewardsRedeemed(opts *bind.FilterOpts, redeemer []common.Address, asset []common.Address) (*TeleporterMessengerRelayerRewardsRedeemedIterator, error) { + + var redeemerRule []interface{} + for _, redeemerItem := range redeemer { + redeemerRule = append(redeemerRule, redeemerItem) + } + var assetRule []interface{} + for _, assetItem := range asset { + assetRule = append(assetRule, assetItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "RelayerRewardsRedeemed", redeemerRule, assetRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerRelayerRewardsRedeemedIterator{contract: _TeleporterMessenger.contract, event: "RelayerRewardsRedeemed", logs: logs, sub: sub}, nil +} + +// WatchRelayerRewardsRedeemed is a free log subscription operation binding the contract event 0x3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88. +// +// Solidity: event RelayerRewardsRedeemed(address indexed redeemer, address indexed asset, uint256 amount) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchRelayerRewardsRedeemed(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerRelayerRewardsRedeemed, redeemer []common.Address, asset []common.Address) (event.Subscription, error) { + + var redeemerRule []interface{} + for _, redeemerItem := range redeemer { + redeemerRule = append(redeemerRule, redeemerItem) + } + var assetRule []interface{} + for _, assetItem := range asset { + assetRule = append(assetRule, assetItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "RelayerRewardsRedeemed", redeemerRule, assetRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerRelayerRewardsRedeemed) + if err := _TeleporterMessenger.contract.UnpackLog(event, "RelayerRewardsRedeemed", 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 +} + +// ParseRelayerRewardsRedeemed is a log parse operation binding the contract event 0x3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88. +// +// Solidity: event RelayerRewardsRedeemed(address indexed redeemer, address indexed asset, uint256 amount) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseRelayerRewardsRedeemed(log types.Log) (*TeleporterMessengerRelayerRewardsRedeemed, error) { + event := new(TeleporterMessengerRelayerRewardsRedeemed) + if err := _TeleporterMessenger.contract.UnpackLog(event, "RelayerRewardsRedeemed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterMessengerSendCrossChainMessageIterator is returned from FilterSendCrossChainMessage and is used to iterate over the raw logs and unpacked data for SendCrossChainMessage events raised by the TeleporterMessenger contract. +type TeleporterMessengerSendCrossChainMessageIterator struct { + Event *TeleporterMessengerSendCrossChainMessage // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterMessengerSendCrossChainMessageIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerSendCrossChainMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterMessengerSendCrossChainMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterMessengerSendCrossChainMessageIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterMessengerSendCrossChainMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterMessengerSendCrossChainMessage represents a SendCrossChainMessage event raised by the TeleporterMessenger contract. +type TeleporterMessengerSendCrossChainMessage struct { + MessageID [32]byte + DestinationBlockchainID [32]byte + Message TeleporterMessage + FeeInfo TeleporterFeeInfo + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSendCrossChainMessage is a free log retrieval operation binding the contract event 0x2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8. +// +// Solidity: event SendCrossChainMessage(bytes32 indexed messageID, bytes32 indexed destinationBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) FilterSendCrossChainMessage(opts *bind.FilterOpts, messageID [][32]byte, destinationBlockchainID [][32]byte) (*TeleporterMessengerSendCrossChainMessageIterator, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var destinationBlockchainIDRule []interface{} + for _, destinationBlockchainIDItem := range destinationBlockchainID { + destinationBlockchainIDRule = append(destinationBlockchainIDRule, destinationBlockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.FilterLogs(opts, "SendCrossChainMessage", messageIDRule, destinationBlockchainIDRule) + if err != nil { + return nil, err + } + return &TeleporterMessengerSendCrossChainMessageIterator{contract: _TeleporterMessenger.contract, event: "SendCrossChainMessage", logs: logs, sub: sub}, nil +} + +// WatchSendCrossChainMessage is a free log subscription operation binding the contract event 0x2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8. +// +// Solidity: event SendCrossChainMessage(bytes32 indexed messageID, bytes32 indexed destinationBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) WatchSendCrossChainMessage(opts *bind.WatchOpts, sink chan<- *TeleporterMessengerSendCrossChainMessage, messageID [][32]byte, destinationBlockchainID [][32]byte) (event.Subscription, error) { + + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + var destinationBlockchainIDRule []interface{} + for _, destinationBlockchainIDItem := range destinationBlockchainID { + destinationBlockchainIDRule = append(destinationBlockchainIDRule, destinationBlockchainIDItem) + } + + logs, sub, err := _TeleporterMessenger.contract.WatchLogs(opts, "SendCrossChainMessage", messageIDRule, destinationBlockchainIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterMessengerSendCrossChainMessage) + if err := _TeleporterMessenger.contract.UnpackLog(event, "SendCrossChainMessage", 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 +} + +// ParseSendCrossChainMessage is a log parse operation binding the contract event 0x2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8. +// +// Solidity: event SendCrossChainMessage(bytes32 indexed messageID, bytes32 indexed destinationBlockchainID, (uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes) message, (address,uint256) feeInfo) +func (_TeleporterMessenger *TeleporterMessengerFilterer) ParseSendCrossChainMessage(log types.Log) (*TeleporterMessengerSendCrossChainMessage, error) { + event := new(TeleporterMessengerSendCrossChainMessage) + if err := _TeleporterMessenger.contract.UnpackLog(event, "SendCrossChainMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/teleporter/TeleporterMessenger/event.go b/abi-bindings/go/teleporter/TeleporterMessenger/event.go new file mode 100644 index 000000000..6bdd244f2 --- /dev/null +++ b/abi-bindings/go/teleporter/TeleporterMessenger/event.go @@ -0,0 +1,261 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package teleportermessenger + +import ( + "encoding/json" + "fmt" + "math/big" + "strings" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" +) + +// Event is a Teleporter log event +type Event uint8 + +const ( + Unknown Event = iota + SendCrossChainMessage + ReceiveCrossChainMessage + AddFeeAmount + MessageExecutionFailed + MessageExecuted + RelayerRewardsRedeemed + ReceiptReceived + + sendCrossChainMessageStr = "SendCrossChainMessage" + receiveCrossChainMessageStr = "ReceiveCrossChainMessage" + addFeeAmountStr = "AddFeeAmount" + messageExecutionFailedStr = "MessageExecutionFailed" + messageExecutedStr = "MessageExecuted" + relayerRewardsRedeemedStr = "RelayerRewardsRedeemed" + receiptReceivedStr = "ReceiptReceived" + unknownStr = "Unknown" +) + +// String returns the string representation of an Event +func (e Event) String() string { + switch e { + case SendCrossChainMessage: + return sendCrossChainMessageStr + case ReceiveCrossChainMessage: + return receiveCrossChainMessageStr + case AddFeeAmount: + return addFeeAmountStr + case MessageExecutionFailed: + return messageExecutionFailedStr + case MessageExecuted: + return messageExecutedStr + case RelayerRewardsRedeemed: + return relayerRewardsRedeemedStr + case ReceiptReceived: + return receiptReceivedStr + default: + return unknownStr + } +} + +// ToEvent converts a string to an Event +func ToEvent(e string) (Event, error) { + switch strings.ToLower(e) { + case strings.ToLower(sendCrossChainMessageStr): + return SendCrossChainMessage, nil + case strings.ToLower(receiveCrossChainMessageStr): + return ReceiveCrossChainMessage, nil + case strings.ToLower(addFeeAmountStr): + return AddFeeAmount, nil + case strings.ToLower(messageExecutionFailedStr): + return MessageExecutionFailed, nil + case strings.ToLower(messageExecutedStr): + return MessageExecuted, nil + case strings.ToLower(relayerRewardsRedeemedStr): + return RelayerRewardsRedeemed, nil + case strings.ToLower(receiptReceivedStr): + return ReceiptReceived, nil + default: + return Unknown, fmt.Errorf("unknown event %s", e) + } +} + +// FilterTeleporterEvents parses the topics and data of a Teleporter log into the corresponding Teleporter event +func FilterTeleporterEvents(topics []common.Hash, data []byte, event string) (fmt.Stringer, error) { + e, err := ToEvent(event) + if err != nil { + return nil, err + } + var out fmt.Stringer + switch e { + case SendCrossChainMessage: + out = new(TeleporterMessengerSendCrossChainMessage) + case ReceiveCrossChainMessage: + out = new(TeleporterMessengerReceiveCrossChainMessage) + case AddFeeAmount: + out = new(TeleporterMessengerAddFeeAmount) + case MessageExecutionFailed: + out = new(TeleporterMessengerMessageExecutionFailed) + case MessageExecuted: + out = new(TeleporterMessengerMessageExecuted) + case RelayerRewardsRedeemed: + out = new(TeleporterMessengerRelayerRewardsRedeemed) + case ReceiptReceived: + out = new(TeleporterMessengerReceiptReceived) + default: + return nil, fmt.Errorf("unknown event %s", e.String()) + } + if err := UnpackEvent(out, e.String(), topics, data); err != nil { + return nil, err + } + return out, nil +} + +func (t TeleporterMessengerSendCrossChainMessage) String() string { + outJson, _ := json.MarshalIndent(ReadableTeleporterMessengerSendCrossChainMessage{ + MessageID: common.Hash(t.MessageID), + DestinationBlockchainID: ids.ID(t.DestinationBlockchainID), + Message: toReadableTeleporterMessage(t.Message), + FeeInfo: t.FeeInfo, + Raw: t.Raw, + }, "", " ") + + return string(outJson) +} + +type ReadableTeleporterMessengerSendCrossChainMessage struct { + MessageID common.Hash + DestinationBlockchainID ids.ID + Message ReadableTeleporterMessage + FeeInfo TeleporterFeeInfo + Raw types.Log +} + +func (t TeleporterMessengerReceiveCrossChainMessage) String() string { + outJson, _ := json.MarshalIndent(ReadableTeleporterMessengerReceiveCrossChainMessage{ + MessageID: common.Hash(t.MessageID), + SourceBlockchainID: ids.ID(t.SourceBlockchainID), + Deliverer: t.Deliverer, + RewardRedeemer: t.RewardRedeemer, + Message: toReadableTeleporterMessage(t.Message), + Raw: t.Raw, + }, "", " ") + + return string(outJson) +} + +type ReadableTeleporterMessengerReceiveCrossChainMessage struct { + MessageID common.Hash + SourceBlockchainID ids.ID + Deliverer common.Address + RewardRedeemer common.Address + Message ReadableTeleporterMessage + Raw types.Log +} + +func (t TeleporterMessengerAddFeeAmount) String() string { + outJson, _ := json.MarshalIndent(ReadableTeleporterMessengerAddFeeAmount{ + MessageID: common.Hash(t.MessageID), + UpdatedFeeInfo: t.UpdatedFeeInfo, + Raw: t.Raw, + }, "", " ") + + return string(outJson) +} + +type ReadableTeleporterMessengerAddFeeAmount struct { + MessageID common.Hash + UpdatedFeeInfo TeleporterFeeInfo + Raw types.Log +} + +func (t TeleporterMessengerMessageExecutionFailed) String() string { + outJson, _ := json.MarshalIndent(ReadableTeleporterMessengerMessageExecutionFailed{ + MessageID: common.Hash(t.MessageID), + SourceBlockchainID: ids.ID(t.SourceBlockchainID), + Message: toReadableTeleporterMessage(t.Message), + Raw: t.Raw, + }, "", " ") + + return string(outJson) +} + +type ReadableTeleporterMessengerMessageExecutionFailed struct { + MessageID common.Hash + SourceBlockchainID ids.ID + Message ReadableTeleporterMessage + Raw types.Log +} + +func (t TeleporterMessengerMessageExecuted) String() string { + outJson, _ := json.MarshalIndent(ReadableTeleporterMessengerMessageExecuted{ + MessageID: common.Hash(t.MessageID), + SourceBlockchainID: ids.ID(t.SourceBlockchainID), + Raw: t.Raw, + }, "", " ") + + return string(outJson) +} + +type ReadableTeleporterMessengerMessageExecuted struct { + MessageID common.Hash + SourceBlockchainID ids.ID + Raw types.Log +} + +func (t TeleporterMessengerRelayerRewardsRedeemed) String() string { + outJson, _ := json.MarshalIndent(t, "", " ") + + return string(outJson) +} + +func (t TeleporterMessengerReceiptReceived) String() string { + outJson, _ := json.MarshalIndent(ReadableTeleporterMessengerReceiptReceived{ + MessageID: common.Hash(t.MessageID), + DestinationBlockchainID: ids.ID(t.DestinationBlockchainID), + RelayerRewardAddress: t.RelayerRewardAddress, + FeeInfo: t.FeeInfo, + Raw: t.Raw, + }, "", " ") + + return string(outJson) +} + +type ReadableTeleporterMessengerReceiptReceived struct { + MessageID common.Hash + DestinationBlockchainID ids.ID + RelayerRewardAddress common.Address + FeeInfo TeleporterFeeInfo + Raw types.Log +} + +func toReadableTeleporterMessage(t TeleporterMessage) ReadableTeleporterMessage { + return ReadableTeleporterMessage{ + MessageNonce: t.MessageNonce, + OriginSenderAddress: t.OriginSenderAddress, + DestinationBlockchainID: ids.ID(t.DestinationBlockchainID), + DestinationAddress: t.DestinationAddress, + RequiredGasLimit: t.RequiredGasLimit, + AllowedRelayerAddresses: t.AllowedRelayerAddresses, + Receipts: t.Receipts, + Message: t.Message, + } +} + +func (t TeleporterMessage) String() string { + outJson, _ := json.MarshalIndent(toReadableTeleporterMessage(t), "", " ") + + return string(outJson) +} + +type ReadableTeleporterMessage struct { + MessageNonce *big.Int + OriginSenderAddress common.Address + DestinationBlockchainID ids.ID + DestinationAddress common.Address + RequiredGasLimit *big.Int + AllowedRelayerAddresses []common.Address + Receipts []TeleporterMessageReceipt + Message []byte +} diff --git a/abi-bindings/go/teleporter/TeleporterMessenger/event_test.go b/abi-bindings/go/teleporter/TeleporterMessenger/event_test.go new file mode 100644 index 000000000..cf91a11b2 --- /dev/null +++ b/abi-bindings/go/teleporter/TeleporterMessenger/event_test.go @@ -0,0 +1,145 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package teleportermessenger + +import ( + "math/big" + "testing" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/libevm/common" + "github.com/stretchr/testify/require" +) + +func TestEventString(t *testing.T) { + var ( + tests = []struct { + event Event + str string + }{ + {Unknown, unknownStr}, + {SendCrossChainMessage, sendCrossChainMessageStr}, + {ReceiveCrossChainMessage, receiveCrossChainMessageStr}, + {AddFeeAmount, addFeeAmountStr}, + {MessageExecutionFailed, messageExecutionFailedStr}, + {MessageExecuted, messageExecutedStr}, + {RelayerRewardsRedeemed, relayerRewardsRedeemedStr}, + } + ) + + for _, test := range tests { + t.Run(test.event.String(), func(t *testing.T) { + require.Equal(t, test.event.String(), test.str) + }) + } +} + +func TestToEvent(t *testing.T) { + var ( + tests = []struct { + str string + event Event + isError bool + }{ + {unknownStr, Unknown, true}, + {sendCrossChainMessageStr, SendCrossChainMessage, false}, + {receiveCrossChainMessageStr, ReceiveCrossChainMessage, false}, + {addFeeAmountStr, AddFeeAmount, false}, + {messageExecutionFailedStr, MessageExecutionFailed, false}, + {messageExecutedStr, MessageExecuted, false}, + {relayerRewardsRedeemedStr, RelayerRewardsRedeemed, false}, + } + ) + + for _, test := range tests { + t.Run(test.str, func(t *testing.T) { + event, err := ToEvent(test.str) + if test.isError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + require.Equal(t, test.event, event) + }) + } +} + +func TestFilterTeleporterEvents(t *testing.T) { + mockBlockchainID := ids.ID{1, 2, 3, 4} + mockMessageNonce := big.NewInt(8) + mockMessageID := ids.ID{9, 10, 11, 12} + message := createTestTeleporterMessage(mockMessageNonce) + feeInfo := TeleporterFeeInfo{ + FeeTokenAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + Amount: big.NewInt(1), + } + deliverer := common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567") + + teleporterABI, err := TeleporterMessengerMetaData.GetAbi() + require.NoError(t, err) + + var ( + tests = []struct { + event Event + args []interface{} + expected interface{} + }{ + { + event: SendCrossChainMessage, + args: []interface{}{ + mockMessageID, + mockBlockchainID, + message, + feeInfo, + }, + expected: &TeleporterMessengerSendCrossChainMessage{ + MessageID: mockMessageID, + DestinationBlockchainID: mockBlockchainID, + Message: message, + FeeInfo: feeInfo, + }, + }, + { + event: ReceiveCrossChainMessage, + args: []interface{}{ + mockMessageID, + mockBlockchainID, + deliverer, + deliverer, + message, + }, + expected: &TeleporterMessengerReceiveCrossChainMessage{ + MessageID: mockMessageID, + SourceBlockchainID: mockBlockchainID, + Deliverer: deliverer, + RewardRedeemer: deliverer, + Message: message, + }, + }, + { + event: MessageExecuted, + args: []interface{}{ + mockMessageID, + mockBlockchainID, + }, + expected: &TeleporterMessengerMessageExecuted{ + MessageID: mockMessageID, + SourceBlockchainID: mockBlockchainID, + }, + }, + } + ) + + for _, test := range tests { + t.Run(test.event.String(), func(t *testing.T) { + topics, data, err := teleporterABI.PackEvent(test.event.String(), test.args...) + require.NoError(t, err) + + out, err := FilterTeleporterEvents(topics, data, test.event.String()) + require.NoError(t, err) + + require.Equal(t, test.expected, out) + }) + } +} diff --git a/abi-bindings/go/teleporter/TeleporterMessenger/packing.go b/abi-bindings/go/teleporter/TeleporterMessenger/packing.go new file mode 100644 index 000000000..ba52b01b8 --- /dev/null +++ b/abi-bindings/go/teleporter/TeleporterMessenger/packing.go @@ -0,0 +1,166 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package teleportermessenger + +import ( + "fmt" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/pkg/errors" +) + +var teleporterMessageType abi.Type + +func init() { + // Create an ABI binding for TeleporterMessage, defined in ITeleporterMessenger.sol + // abigen does not support ABI bindings for standalone structs, only methods and events, + // so we must manually keep this up-to-date with the struct defined in the contract. + var err error + teleporterMessageType, err = abi.NewType("tuple", "struct Overloader.F", []abi.ArgumentMarshaling{ + {Name: "messageNonce", Type: "uint256"}, + {Name: "originSenderAddress", Type: "address"}, + {Name: "destinationBlockchainID", Type: "bytes32"}, + {Name: "destinationAddress", Type: "address"}, + {Name: "requiredGasLimit", Type: "uint256"}, + {Name: "allowedRelayerAddresses", Type: "address[]"}, + {Name: "receipts", Type: "tuple[]", Components: []abi.ArgumentMarshaling{ + {Name: "receivedMessageNonce", Type: "uint256"}, + {Name: "relayerRewardAddress", Type: "address"}, + }}, + {Name: "message", Type: "bytes"}, + }) + if err != nil { + panic(fmt.Sprintf("failed to create TeleporterMessage ABI type: %v", err)) + } +} + +func (m *TeleporterMessage) Pack() ([]byte, error) { + args := abi.Arguments{ + { + Name: "teleporterMessage", + Type: teleporterMessageType, + }, + } + return args.Pack(m) +} + +func (m *TeleporterMessage) Unpack(b []byte) error { + args := abi.Arguments{ + { + Name: "teleporterMessage", + Type: teleporterMessageType, + }, + } + unpacked, err := args.Unpack(b) + if err != nil { + return fmt.Errorf("failed to unpack to teleporter message with err: %v", err) + } + return args.Copy(&m, unpacked) +} + +func PackSendCrossChainMessage(input TeleporterMessageInput) ([]byte, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + + return abi.Pack("sendCrossChainMessage", input) +} + +func PackRetryMessageExecution(sourceBlockchainID ids.ID, message TeleporterMessage) ([]byte, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + + return abi.Pack("retryMessageExecution", sourceBlockchainID, message) +} + +// PackReceiveCrossChainMessage packs a ReceiveCrossChainMessageInput to form +// a call to the receiveCrossChainMessage function +func PackReceiveCrossChainMessage(messageIndex uint32, relayerRewardAddress common.Address) ([]byte, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + + return abi.Pack("receiveCrossChainMessage", messageIndex, relayerRewardAddress) +} + +// PackCalculateMessageID packs input to form a call to the calculateMessageID function +func PackCalculateMessageID( + sourceBlockchainID [32]byte, + destinationBlockchainID [32]byte, + nonce *big.Int, +) ([]byte, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + + return abi.Pack("calculateMessageID", sourceBlockchainID, destinationBlockchainID, nonce) +} + +func PackCalculateMessageIDOutput(messageID [32]byte) ([]byte, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + + return abi.PackOutput("calculateMessageID", messageID) +} + +// PackMessageReceived packs a MessageReceivedInput to form a call to the messageReceived function +func PackMessageReceived(messageID [32]byte) ([]byte, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + return abi.Pack("messageReceived", messageID) +} + +// UnpackMessageReceivedResult attempts to unpack result bytes to a bool indicating whether the message was received +func UnpackMessageReceivedResult(result []byte) (bool, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return false, errors.Wrap(err, "failed to get abi") + } + + var success bool + err = abi.UnpackIntoInterface(&success, "messageReceived", result) + return success, err +} + +func PackMessageReceivedOutput(success bool) ([]byte, error) { + abi, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + + return abi.PackOutput("messageReceived", success) +} + +// UnpackEvent unpacks the event data and topics into the provided interface +func UnpackEvent(out interface{}, event string, topics []common.Hash, data []byte) error { + teleporterABI, err := TeleporterMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get abi: %v", err) + } + if len(data) > 0 { + if err := teleporterABI.UnpackIntoInterface(out, event, data); err != nil { + return err + } + } + + var indexed abi.Arguments + for _, arg := range teleporterABI.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + return abi.ParseTopics(out, indexed, topics[1:]) +} diff --git a/abi-bindings/go/teleporter/TeleporterMessenger/packing_test.go b/abi-bindings/go/teleporter/TeleporterMessenger/packing_test.go new file mode 100644 index 000000000..855773e9d --- /dev/null +++ b/abi-bindings/go/teleporter/TeleporterMessenger/packing_test.go @@ -0,0 +1,117 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package teleportermessenger + +import ( + "math/big" + "testing" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/libevm/common" + "github.com/stretchr/testify/require" +) + +func createTestTeleporterMessage(messageNonce *big.Int) TeleporterMessage { + m := TeleporterMessage{ + MessageNonce: messageNonce, + OriginSenderAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + DestinationBlockchainID: ids.ID{1, 2, 3, 4}, + DestinationAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + RequiredGasLimit: big.NewInt(2), + AllowedRelayerAddresses: []common.Address{ + common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + }, + Receipts: []TeleporterMessageReceipt{ + { + ReceivedMessageNonce: big.NewInt(1), + RelayerRewardAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + }, + }, + Message: []byte{1, 2, 3, 4}, + } + return m +} + +func TestUnpackEvent(t *testing.T) { + mockBlockchainID := ids.ID{1, 2, 3, 4} + mockMessageNonce := big.NewInt(5) + mockMessageID := common.Hash{9, 10, 11, 12} + message := createTestTeleporterMessage(mockMessageNonce) + feeInfo := TeleporterFeeInfo{ + FeeTokenAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + Amount: big.NewInt(1), + } + deliverer := common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567") + + teleporterABI, err := TeleporterMessengerMetaData.GetAbi() + require.NoError(t, err) + + var ( + tests = []struct { + event Event + args []interface{} + out interface{} + expected interface{} + }{ + { + event: SendCrossChainMessage, + args: []interface{}{ + mockMessageID, + mockBlockchainID, + message, + feeInfo, + }, + out: new(TeleporterMessengerSendCrossChainMessage), + expected: &TeleporterMessengerSendCrossChainMessage{ + DestinationBlockchainID: mockBlockchainID, + MessageID: mockMessageID, + Message: message, + FeeInfo: feeInfo, + }, + }, + { + event: ReceiveCrossChainMessage, + args: []interface{}{ + mockMessageID, + mockBlockchainID, + deliverer, + deliverer, + message, + }, + out: new(TeleporterMessengerReceiveCrossChainMessage), + expected: &TeleporterMessengerReceiveCrossChainMessage{ + SourceBlockchainID: mockBlockchainID, + MessageID: mockMessageID, + Deliverer: deliverer, + RewardRedeemer: deliverer, + Message: message, + }, + }, + { + event: MessageExecuted, + args: []interface{}{ + mockMessageID, + mockBlockchainID, + }, + out: new(TeleporterMessengerMessageExecuted), + expected: &TeleporterMessengerMessageExecuted{ + MessageID: mockMessageID, + SourceBlockchainID: mockBlockchainID, + }, + }, + } + ) + + for _, test := range tests { + t.Run(test.event.String(), func(t *testing.T) { + topics, data, err := teleporterABI.PackEvent(test.event.String(), test.args...) + require.NoError(t, err) + + err = UnpackEvent(test.out, test.event.String(), topics, data) + require.NoError(t, err) + + require.Equal(t, test.expected, test.out) + }) + } +} diff --git a/abi-bindings/go/teleporter/registry/TeleporterRegistry/TeleporterRegistry.go b/abi-bindings/go/teleporter/registry/TeleporterRegistry/TeleporterRegistry.go new file mode 100644 index 000000000..2d978f617 --- /dev/null +++ b/abi-bindings/go/teleporter/registry/TeleporterRegistry/TeleporterRegistry.go @@ -0,0 +1,815 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package teleporterregistry + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ProtocolRegistryEntry is an auto generated low-level Go binding around an user-defined struct. +type ProtocolRegistryEntry struct { + Version *big.Int + ProtocolAddress common.Address +} + +// TeleporterRegistryMetaData contains all meta data concerning the TeleporterRegistry contract. +var TeleporterRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"protocolAddress\",\"type\":\"address\"}],\"internalType\":\"structProtocolRegistryEntry[]\",\"name\":\"initialEntries\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"protocolAddress\",\"type\":\"address\"}],\"name\":\"AddProtocolVersion\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newVersion\",\"type\":\"uint256\"}],\"name\":\"LatestVersionUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_VERSION_INCREMENT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VALIDATORS_SOURCE_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WARP_MESSENGER\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"addProtocolVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"getAddressFromVersion\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestTeleporter\",\"outputs\":[{\"internalType\":\"contractITeleporterMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"getTeleporterFromVersion\",\"outputs\":[{\"internalType\":\"contractITeleporterMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"protocolAddress\",\"type\":\"address\"}],\"name\":\"getVersionFromAddress\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561000f575f80fd5b50604051610fe0380380610fe083398101604081905261002e916103e2565b7302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801561007e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100a291906104bc565b60805280515f5b818110156100e1576100d98382815181106100c6576100c66104d3565b60200260200101516100e960201b60201c565b6001016100a9565b50505061050c565b80515f0361013e5760405162461bcd60e51b815260206004820181905260248201527f54656c65706f7274657252656769737472793a207a65726f2076657273696f6e60448201526064015b60405180910390fd5b80515f908152600160205260409020546001600160a01b0316156101b75760405162461bcd60e51b815260206004820152602a60248201527f54656c65706f7274657252656769737472793a2076657273696f6e20616c72656044820152696164792065786973747360b01b6064820152608401610135565b60208101516001600160a01b03166102235760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472793a207a65726f2070726f746f636f6044820152686c206164647265737360b81b6064820152608401610135565b5f546102316101f4826104e7565b825111156102985760405162461bcd60e51b815260206004820152602e60248201527f54656c65706f7274657252656769737472793a2076657273696f6e20696e637260448201526d0cadacadce840e8dede40d0d2ced60931b6064820152608401610135565b6020828101805184515f90815260018452604080822080546001600160a01b0319166001600160a01b03948516179055925190911681526002909252902054825111156102ff5781516020808401516001600160a01b03165f908152600290915260409020555b602082015182516040516001600160a01b03909216917fa5eed93d951a9603d5f7c0a57de79a299dd3dbd5e51429be209d8053a42ab43a905f90a381518110156103725781515f81815560405183917f30623e953733f6474dabdfbef1103ce15ab73cdc77c6dfad0f9874d167e8a9b091a35b5050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156103ac576103ac610376565b60405290565b604051601f8201601f191681016001600160401b03811182821017156103da576103da610376565b604052919050565b5f60208083850312156103f3575f80fd5b82516001600160401b0380821115610409575f80fd5b818501915085601f83011261041c575f80fd5b81518181111561042e5761042e610376565b61043c848260051b016103b2565b818152848101925060069190911b83018401908782111561045b575f80fd5b928401925b818410156104b15760408489031215610477575f80fd5b61047f61038a565b84518152858501516001600160a01b038116811461049b575f80fd5b8187015283526040939093019291840191610460565b979650505050505050565b5f602082840312156104cc575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b8082018082111561050657634e487b7160e01b5f52601160045260245ffd5b92915050565b608051610ab561052b5f395f818161014301526102580152610ab55ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c8063ac473ac311610063578063ac473ac31461011f578063b771b3bc14610128578063c07f47d414610136578063d127dc9b1461013e578063d820e64f14610165575f80fd5b80630731775d1461009f578063215abce9146100c357806341f34ed9146100d657806346f9ef49146100eb5780634c1f08ce146100fe575b5f80fd5b6100a65f81565b6040516001600160a01b0390911681526020015b60405180910390f35b6100a66100d13660046107aa565b61016d565b6100e96100e43660046107c1565b61017d565b005b6100a66100f93660046107aa565b6103ec565b61011161010c366004610802565b6104ae565b6040519081526020016100ba565b6101116101f481565b6100a66005600160991b0181565b6101115f5481565b6101117f000000000000000000000000000000000000000000000000000000000000000081565b6100a6610554565b5f610177826103ec565b92915050565b6040516306f8253560e41b815263ffffffff821660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa1580156101c6573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526101ed919081019061089f565b91509150806102545760405162461bcd60e51b815260206004820152602860248201527f54656c65706f7274657252656769737472793a20696e76616c69642077617270604482015267206d65737361676560c01b60648201526084015b60405180910390fd5b81517f0000000000000000000000000000000000000000000000000000000000000000146102d85760405162461bcd60e51b815260206004820152602b60248201527f54656c65706f7274657252656769737472793a20696e76616c696420736f757260448201526a18d94818da185a5b88125160aa1b606482015260840161024b565b60208201516001600160a01b03161561034d5760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472793a20696e76616c6964206f726967604482015270696e2073656e646572206164647265737360781b606482015260840161024b565b5f808360400151806020019051810190610367919061099e565b90925090506001600160a01b03811630146103dc5760405162461bcd60e51b815260206004820152602f60248201527f54656c65706f7274657252656769737472793a20696e76616c6964206465737460448201526e696e6174696f6e206164647265737360881b606482015260840161024b565b6103e582610564565b5050505050565b5f815f0361043c5760405162461bcd60e51b815260206004820181905260248201527f54656c65706f7274657252656769737472793a207a65726f2076657273696f6e604482015260640161024b565b5f828152600160205260409020546001600160a01b0316806101775760405162461bcd60e51b815260206004820152602560248201527f54656c65706f7274657252656769737472793a2076657273696f6e206e6f7420604482015264199bdd5b9960da1b606482015260840161024b565b5f6001600160a01b0382166104d55760405162461bcd60e51b815260040161024b90610a17565b6001600160a01b0382165f90815260026020526040812054908190036101775760405162461bcd60e51b815260206004820152602e60248201527f54656c65706f7274657252656769737472793a2070726f746f636f6c2061646460448201526d1c995cdcc81b9bdd08199bdd5b9960921b606482015260840161024b565b5f61055f5f546103ec565b905090565b80515f036105b45760405162461bcd60e51b815260206004820181905260248201527f54656c65706f7274657252656769737472793a207a65726f2076657273696f6e604482015260640161024b565b80515f908152600160205260409020546001600160a01b03161561062d5760405162461bcd60e51b815260206004820152602a60248201527f54656c65706f7274657252656769737472793a2076657273696f6e20616c72656044820152696164792065786973747360b01b606482015260840161024b565b60208101516001600160a01b03166106575760405162461bcd60e51b815260040161024b90610a17565b5f546106656101f482610a60565b825111156106cc5760405162461bcd60e51b815260206004820152602e60248201527f54656c65706f7274657252656769737472793a2076657273696f6e20696e637260448201526d0cadacadce840e8dede40d0d2ced60931b606482015260840161024b565b6020828101805184515f90815260018452604080822080546001600160a01b0319166001600160a01b03948516179055925190911681526002909252902054825111156107335781516020808401516001600160a01b03165f908152600290915260409020555b602082015182516040516001600160a01b03909216917fa5eed93d951a9603d5f7c0a57de79a299dd3dbd5e51429be209d8053a42ab43a905f90a381518110156107a65781515f81815560405183917f30623e953733f6474dabdfbef1103ce15ab73cdc77c6dfad0f9874d167e8a9b091a35b5050565b5f602082840312156107ba575f80fd5b5035919050565b5f602082840312156107d1575f80fd5b813563ffffffff811681146107e4575f80fd5b9392505050565b6001600160a01b03811681146107ff575f80fd5b50565b5f60208284031215610812575f80fd5b81356107e4816107eb565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff811182821017156108545761085461081d565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156108835761088361081d565b604052919050565b8051801515811461089a575f80fd5b919050565b5f80604083850312156108b0575f80fd5b825167ffffffffffffffff808211156108c7575f80fd5b90840190606082870312156108da575f80fd5b6108e2610831565b825181526020808401516108f5816107eb565b8282015260408401518381111561090a575f80fd5b80850194505087601f85011261091e575f80fd5b8351838111156109305761093061081d565b610942601f8201601f1916830161085a565b93508084528882828701011115610957575f80fd5b5f5b81811015610974578581018301518582018401528201610959565b505f8282860101525082604083015281955061099181880161088b565b9450505050509250929050565b5f8082840360608112156109b0575f80fd5b60408112156109bd575f80fd5b506040516040810181811067ffffffffffffffff821117156109e1576109e161081d565b6040528351815260208401516109f6816107eb565b60208201526040840151909250610a0c816107eb565b809150509250929050565b60208082526029908201527f54656c65706f7274657252656769737472793a207a65726f2070726f746f636f6040820152686c206164647265737360b81b606082015260800190565b8082018082111561017757634e487b7160e01b5f52601160045260245ffdfea26469706673582212209df9e1da8e38c899313dfdb8c7b5dbf1138454fb82451ed2db3a7418a36ebd7464736f6c63430008190033", +} + +// TeleporterRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use TeleporterRegistryMetaData.ABI instead. +var TeleporterRegistryABI = TeleporterRegistryMetaData.ABI + +// TeleporterRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TeleporterRegistryMetaData.Bin instead. +var TeleporterRegistryBin = TeleporterRegistryMetaData.Bin + +// DeployTeleporterRegistry deploys a new Ethereum contract, binding an instance of TeleporterRegistry to it. +func DeployTeleporterRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, initialEntries []ProtocolRegistryEntry) (common.Address, *types.Transaction, *TeleporterRegistry, error) { + parsed, err := TeleporterRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TeleporterRegistryBin), backend, initialEntries) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TeleporterRegistry{TeleporterRegistryCaller: TeleporterRegistryCaller{contract: contract}, TeleporterRegistryTransactor: TeleporterRegistryTransactor{contract: contract}, TeleporterRegistryFilterer: TeleporterRegistryFilterer{contract: contract}}, nil +} + +// TeleporterRegistry is an auto generated Go binding around an Ethereum contract. +type TeleporterRegistry struct { + TeleporterRegistryCaller // Read-only binding to the contract + TeleporterRegistryTransactor // Write-only binding to the contract + TeleporterRegistryFilterer // Log filterer for contract events +} + +// TeleporterRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type TeleporterRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TeleporterRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TeleporterRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TeleporterRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TeleporterRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TeleporterRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TeleporterRegistrySession struct { + Contract *TeleporterRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TeleporterRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TeleporterRegistryCallerSession struct { + Contract *TeleporterRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TeleporterRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TeleporterRegistryTransactorSession struct { + Contract *TeleporterRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TeleporterRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type TeleporterRegistryRaw struct { + Contract *TeleporterRegistry // Generic contract binding to access the raw methods on +} + +// TeleporterRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TeleporterRegistryCallerRaw struct { + Contract *TeleporterRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// TeleporterRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TeleporterRegistryTransactorRaw struct { + Contract *TeleporterRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTeleporterRegistry creates a new instance of TeleporterRegistry, bound to a specific deployed contract. +func NewTeleporterRegistry(address common.Address, backend bind.ContractBackend) (*TeleporterRegistry, error) { + contract, err := bindTeleporterRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TeleporterRegistry{TeleporterRegistryCaller: TeleporterRegistryCaller{contract: contract}, TeleporterRegistryTransactor: TeleporterRegistryTransactor{contract: contract}, TeleporterRegistryFilterer: TeleporterRegistryFilterer{contract: contract}}, nil +} + +// NewTeleporterRegistryCaller creates a new read-only instance of TeleporterRegistry, bound to a specific deployed contract. +func NewTeleporterRegistryCaller(address common.Address, caller bind.ContractCaller) (*TeleporterRegistryCaller, error) { + contract, err := bindTeleporterRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TeleporterRegistryCaller{contract: contract}, nil +} + +// NewTeleporterRegistryTransactor creates a new write-only instance of TeleporterRegistry, bound to a specific deployed contract. +func NewTeleporterRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*TeleporterRegistryTransactor, error) { + contract, err := bindTeleporterRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TeleporterRegistryTransactor{contract: contract}, nil +} + +// NewTeleporterRegistryFilterer creates a new log filterer instance of TeleporterRegistry, bound to a specific deployed contract. +func NewTeleporterRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*TeleporterRegistryFilterer, error) { + contract, err := bindTeleporterRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TeleporterRegistryFilterer{contract: contract}, nil +} + +// bindTeleporterRegistry binds a generic wrapper to an already deployed contract. +func bindTeleporterRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TeleporterRegistryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TeleporterRegistry *TeleporterRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TeleporterRegistry.Contract.TeleporterRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TeleporterRegistry *TeleporterRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TeleporterRegistry.Contract.TeleporterRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TeleporterRegistry *TeleporterRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TeleporterRegistry.Contract.TeleporterRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TeleporterRegistry *TeleporterRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TeleporterRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TeleporterRegistry *TeleporterRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TeleporterRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TeleporterRegistry *TeleporterRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TeleporterRegistry.Contract.contract.Transact(opts, method, params...) +} + +// MAXVERSIONINCREMENT is a free data retrieval call binding the contract method 0xac473ac3. +// +// Solidity: function MAX_VERSION_INCREMENT() view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistryCaller) MAXVERSIONINCREMENT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "MAX_VERSION_INCREMENT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MAXVERSIONINCREMENT is a free data retrieval call binding the contract method 0xac473ac3. +// +// Solidity: function MAX_VERSION_INCREMENT() view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistrySession) MAXVERSIONINCREMENT() (*big.Int, error) { + return _TeleporterRegistry.Contract.MAXVERSIONINCREMENT(&_TeleporterRegistry.CallOpts) +} + +// MAXVERSIONINCREMENT is a free data retrieval call binding the contract method 0xac473ac3. +// +// Solidity: function MAX_VERSION_INCREMENT() view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) MAXVERSIONINCREMENT() (*big.Int, error) { + return _TeleporterRegistry.Contract.MAXVERSIONINCREMENT(&_TeleporterRegistry.CallOpts) +} + +// VALIDATORSSOURCEADDRESS is a free data retrieval call binding the contract method 0x0731775d. +// +// Solidity: function VALIDATORS_SOURCE_ADDRESS() view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCaller) VALIDATORSSOURCEADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "VALIDATORS_SOURCE_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// VALIDATORSSOURCEADDRESS is a free data retrieval call binding the contract method 0x0731775d. +// +// Solidity: function VALIDATORS_SOURCE_ADDRESS() view returns(address) +func (_TeleporterRegistry *TeleporterRegistrySession) VALIDATORSSOURCEADDRESS() (common.Address, error) { + return _TeleporterRegistry.Contract.VALIDATORSSOURCEADDRESS(&_TeleporterRegistry.CallOpts) +} + +// VALIDATORSSOURCEADDRESS is a free data retrieval call binding the contract method 0x0731775d. +// +// Solidity: function VALIDATORS_SOURCE_ADDRESS() view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) VALIDATORSSOURCEADDRESS() (common.Address, error) { + return _TeleporterRegistry.Contract.VALIDATORSSOURCEADDRESS(&_TeleporterRegistry.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_TeleporterRegistry *TeleporterRegistrySession) WARPMESSENGER() (common.Address, error) { + return _TeleporterRegistry.Contract.WARPMESSENGER(&_TeleporterRegistry.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) WARPMESSENGER() (common.Address, error) { + return _TeleporterRegistry.Contract.WARPMESSENGER(&_TeleporterRegistry.CallOpts) +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_TeleporterRegistry *TeleporterRegistryCaller) BlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "blockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_TeleporterRegistry *TeleporterRegistrySession) BlockchainID() ([32]byte, error) { + return _TeleporterRegistry.Contract.BlockchainID(&_TeleporterRegistry.CallOpts) +} + +// BlockchainID is a free data retrieval call binding the contract method 0xd127dc9b. +// +// Solidity: function blockchainID() view returns(bytes32) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) BlockchainID() ([32]byte, error) { + return _TeleporterRegistry.Contract.BlockchainID(&_TeleporterRegistry.CallOpts) +} + +// GetAddressFromVersion is a free data retrieval call binding the contract method 0x46f9ef49. +// +// Solidity: function getAddressFromVersion(uint256 version) view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCaller) GetAddressFromVersion(opts *bind.CallOpts, version *big.Int) (common.Address, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "getAddressFromVersion", version) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetAddressFromVersion is a free data retrieval call binding the contract method 0x46f9ef49. +// +// Solidity: function getAddressFromVersion(uint256 version) view returns(address) +func (_TeleporterRegistry *TeleporterRegistrySession) GetAddressFromVersion(version *big.Int) (common.Address, error) { + return _TeleporterRegistry.Contract.GetAddressFromVersion(&_TeleporterRegistry.CallOpts, version) +} + +// GetAddressFromVersion is a free data retrieval call binding the contract method 0x46f9ef49. +// +// Solidity: function getAddressFromVersion(uint256 version) view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) GetAddressFromVersion(version *big.Int) (common.Address, error) { + return _TeleporterRegistry.Contract.GetAddressFromVersion(&_TeleporterRegistry.CallOpts, version) +} + +// GetLatestTeleporter is a free data retrieval call binding the contract method 0xd820e64f. +// +// Solidity: function getLatestTeleporter() view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCaller) GetLatestTeleporter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "getLatestTeleporter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetLatestTeleporter is a free data retrieval call binding the contract method 0xd820e64f. +// +// Solidity: function getLatestTeleporter() view returns(address) +func (_TeleporterRegistry *TeleporterRegistrySession) GetLatestTeleporter() (common.Address, error) { + return _TeleporterRegistry.Contract.GetLatestTeleporter(&_TeleporterRegistry.CallOpts) +} + +// GetLatestTeleporter is a free data retrieval call binding the contract method 0xd820e64f. +// +// Solidity: function getLatestTeleporter() view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) GetLatestTeleporter() (common.Address, error) { + return _TeleporterRegistry.Contract.GetLatestTeleporter(&_TeleporterRegistry.CallOpts) +} + +// GetTeleporterFromVersion is a free data retrieval call binding the contract method 0x215abce9. +// +// Solidity: function getTeleporterFromVersion(uint256 version) view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCaller) GetTeleporterFromVersion(opts *bind.CallOpts, version *big.Int) (common.Address, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "getTeleporterFromVersion", version) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTeleporterFromVersion is a free data retrieval call binding the contract method 0x215abce9. +// +// Solidity: function getTeleporterFromVersion(uint256 version) view returns(address) +func (_TeleporterRegistry *TeleporterRegistrySession) GetTeleporterFromVersion(version *big.Int) (common.Address, error) { + return _TeleporterRegistry.Contract.GetTeleporterFromVersion(&_TeleporterRegistry.CallOpts, version) +} + +// GetTeleporterFromVersion is a free data retrieval call binding the contract method 0x215abce9. +// +// Solidity: function getTeleporterFromVersion(uint256 version) view returns(address) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) GetTeleporterFromVersion(version *big.Int) (common.Address, error) { + return _TeleporterRegistry.Contract.GetTeleporterFromVersion(&_TeleporterRegistry.CallOpts, version) +} + +// GetVersionFromAddress is a free data retrieval call binding the contract method 0x4c1f08ce. +// +// Solidity: function getVersionFromAddress(address protocolAddress) view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistryCaller) GetVersionFromAddress(opts *bind.CallOpts, protocolAddress common.Address) (*big.Int, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "getVersionFromAddress", protocolAddress) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetVersionFromAddress is a free data retrieval call binding the contract method 0x4c1f08ce. +// +// Solidity: function getVersionFromAddress(address protocolAddress) view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistrySession) GetVersionFromAddress(protocolAddress common.Address) (*big.Int, error) { + return _TeleporterRegistry.Contract.GetVersionFromAddress(&_TeleporterRegistry.CallOpts, protocolAddress) +} + +// GetVersionFromAddress is a free data retrieval call binding the contract method 0x4c1f08ce. +// +// Solidity: function getVersionFromAddress(address protocolAddress) view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) GetVersionFromAddress(protocolAddress common.Address) (*big.Int, error) { + return _TeleporterRegistry.Contract.GetVersionFromAddress(&_TeleporterRegistry.CallOpts, protocolAddress) +} + +// LatestVersion is a free data retrieval call binding the contract method 0xc07f47d4. +// +// Solidity: function latestVersion() view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistryCaller) LatestVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TeleporterRegistry.contract.Call(opts, &out, "latestVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// LatestVersion is a free data retrieval call binding the contract method 0xc07f47d4. +// +// Solidity: function latestVersion() view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistrySession) LatestVersion() (*big.Int, error) { + return _TeleporterRegistry.Contract.LatestVersion(&_TeleporterRegistry.CallOpts) +} + +// LatestVersion is a free data retrieval call binding the contract method 0xc07f47d4. +// +// Solidity: function latestVersion() view returns(uint256) +func (_TeleporterRegistry *TeleporterRegistryCallerSession) LatestVersion() (*big.Int, error) { + return _TeleporterRegistry.Contract.LatestVersion(&_TeleporterRegistry.CallOpts) +} + +// AddProtocolVersion is a paid mutator transaction binding the contract method 0x41f34ed9. +// +// Solidity: function addProtocolVersion(uint32 messageIndex) returns() +func (_TeleporterRegistry *TeleporterRegistryTransactor) AddProtocolVersion(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _TeleporterRegistry.contract.Transact(opts, "addProtocolVersion", messageIndex) +} + +// AddProtocolVersion is a paid mutator transaction binding the contract method 0x41f34ed9. +// +// Solidity: function addProtocolVersion(uint32 messageIndex) returns() +func (_TeleporterRegistry *TeleporterRegistrySession) AddProtocolVersion(messageIndex uint32) (*types.Transaction, error) { + return _TeleporterRegistry.Contract.AddProtocolVersion(&_TeleporterRegistry.TransactOpts, messageIndex) +} + +// AddProtocolVersion is a paid mutator transaction binding the contract method 0x41f34ed9. +// +// Solidity: function addProtocolVersion(uint32 messageIndex) returns() +func (_TeleporterRegistry *TeleporterRegistryTransactorSession) AddProtocolVersion(messageIndex uint32) (*types.Transaction, error) { + return _TeleporterRegistry.Contract.AddProtocolVersion(&_TeleporterRegistry.TransactOpts, messageIndex) +} + +// TeleporterRegistryAddProtocolVersionIterator is returned from FilterAddProtocolVersion and is used to iterate over the raw logs and unpacked data for AddProtocolVersion events raised by the TeleporterRegistry contract. +type TeleporterRegistryAddProtocolVersionIterator struct { + Event *TeleporterRegistryAddProtocolVersion // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterRegistryAddProtocolVersionIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterRegistryAddProtocolVersion) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterRegistryAddProtocolVersion) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterRegistryAddProtocolVersionIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterRegistryAddProtocolVersionIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterRegistryAddProtocolVersion represents a AddProtocolVersion event raised by the TeleporterRegistry contract. +type TeleporterRegistryAddProtocolVersion struct { + Version *big.Int + ProtocolAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAddProtocolVersion is a free log retrieval operation binding the contract event 0xa5eed93d951a9603d5f7c0a57de79a299dd3dbd5e51429be209d8053a42ab43a. +// +// Solidity: event AddProtocolVersion(uint256 indexed version, address indexed protocolAddress) +func (_TeleporterRegistry *TeleporterRegistryFilterer) FilterAddProtocolVersion(opts *bind.FilterOpts, version []*big.Int, protocolAddress []common.Address) (*TeleporterRegistryAddProtocolVersionIterator, error) { + + var versionRule []interface{} + for _, versionItem := range version { + versionRule = append(versionRule, versionItem) + } + var protocolAddressRule []interface{} + for _, protocolAddressItem := range protocolAddress { + protocolAddressRule = append(protocolAddressRule, protocolAddressItem) + } + + logs, sub, err := _TeleporterRegistry.contract.FilterLogs(opts, "AddProtocolVersion", versionRule, protocolAddressRule) + if err != nil { + return nil, err + } + return &TeleporterRegistryAddProtocolVersionIterator{contract: _TeleporterRegistry.contract, event: "AddProtocolVersion", logs: logs, sub: sub}, nil +} + +// WatchAddProtocolVersion is a free log subscription operation binding the contract event 0xa5eed93d951a9603d5f7c0a57de79a299dd3dbd5e51429be209d8053a42ab43a. +// +// Solidity: event AddProtocolVersion(uint256 indexed version, address indexed protocolAddress) +func (_TeleporterRegistry *TeleporterRegistryFilterer) WatchAddProtocolVersion(opts *bind.WatchOpts, sink chan<- *TeleporterRegistryAddProtocolVersion, version []*big.Int, protocolAddress []common.Address) (event.Subscription, error) { + + var versionRule []interface{} + for _, versionItem := range version { + versionRule = append(versionRule, versionItem) + } + var protocolAddressRule []interface{} + for _, protocolAddressItem := range protocolAddress { + protocolAddressRule = append(protocolAddressRule, protocolAddressItem) + } + + logs, sub, err := _TeleporterRegistry.contract.WatchLogs(opts, "AddProtocolVersion", versionRule, protocolAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterRegistryAddProtocolVersion) + if err := _TeleporterRegistry.contract.UnpackLog(event, "AddProtocolVersion", 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 +} + +// ParseAddProtocolVersion is a log parse operation binding the contract event 0xa5eed93d951a9603d5f7c0a57de79a299dd3dbd5e51429be209d8053a42ab43a. +// +// Solidity: event AddProtocolVersion(uint256 indexed version, address indexed protocolAddress) +func (_TeleporterRegistry *TeleporterRegistryFilterer) ParseAddProtocolVersion(log types.Log) (*TeleporterRegistryAddProtocolVersion, error) { + event := new(TeleporterRegistryAddProtocolVersion) + if err := _TeleporterRegistry.contract.UnpackLog(event, "AddProtocolVersion", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TeleporterRegistryLatestVersionUpdatedIterator is returned from FilterLatestVersionUpdated and is used to iterate over the raw logs and unpacked data for LatestVersionUpdated events raised by the TeleporterRegistry contract. +type TeleporterRegistryLatestVersionUpdatedIterator struct { + Event *TeleporterRegistryLatestVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TeleporterRegistryLatestVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TeleporterRegistryLatestVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TeleporterRegistryLatestVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TeleporterRegistryLatestVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TeleporterRegistryLatestVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TeleporterRegistryLatestVersionUpdated represents a LatestVersionUpdated event raised by the TeleporterRegistry contract. +type TeleporterRegistryLatestVersionUpdated struct { + OldVersion *big.Int + NewVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterLatestVersionUpdated is a free log retrieval operation binding the contract event 0x30623e953733f6474dabdfbef1103ce15ab73cdc77c6dfad0f9874d167e8a9b0. +// +// Solidity: event LatestVersionUpdated(uint256 indexed oldVersion, uint256 indexed newVersion) +func (_TeleporterRegistry *TeleporterRegistryFilterer) FilterLatestVersionUpdated(opts *bind.FilterOpts, oldVersion []*big.Int, newVersion []*big.Int) (*TeleporterRegistryLatestVersionUpdatedIterator, error) { + + var oldVersionRule []interface{} + for _, oldVersionItem := range oldVersion { + oldVersionRule = append(oldVersionRule, oldVersionItem) + } + var newVersionRule []interface{} + for _, newVersionItem := range newVersion { + newVersionRule = append(newVersionRule, newVersionItem) + } + + logs, sub, err := _TeleporterRegistry.contract.FilterLogs(opts, "LatestVersionUpdated", oldVersionRule, newVersionRule) + if err != nil { + return nil, err + } + return &TeleporterRegistryLatestVersionUpdatedIterator{contract: _TeleporterRegistry.contract, event: "LatestVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchLatestVersionUpdated is a free log subscription operation binding the contract event 0x30623e953733f6474dabdfbef1103ce15ab73cdc77c6dfad0f9874d167e8a9b0. +// +// Solidity: event LatestVersionUpdated(uint256 indexed oldVersion, uint256 indexed newVersion) +func (_TeleporterRegistry *TeleporterRegistryFilterer) WatchLatestVersionUpdated(opts *bind.WatchOpts, sink chan<- *TeleporterRegistryLatestVersionUpdated, oldVersion []*big.Int, newVersion []*big.Int) (event.Subscription, error) { + + var oldVersionRule []interface{} + for _, oldVersionItem := range oldVersion { + oldVersionRule = append(oldVersionRule, oldVersionItem) + } + var newVersionRule []interface{} + for _, newVersionItem := range newVersion { + newVersionRule = append(newVersionRule, newVersionItem) + } + + logs, sub, err := _TeleporterRegistry.contract.WatchLogs(opts, "LatestVersionUpdated", oldVersionRule, newVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TeleporterRegistryLatestVersionUpdated) + if err := _TeleporterRegistry.contract.UnpackLog(event, "LatestVersionUpdated", 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 +} + +// ParseLatestVersionUpdated is a log parse operation binding the contract event 0x30623e953733f6474dabdfbef1103ce15ab73cdc77c6dfad0f9874d167e8a9b0. +// +// Solidity: event LatestVersionUpdated(uint256 indexed oldVersion, uint256 indexed newVersion) +func (_TeleporterRegistry *TeleporterRegistryFilterer) ParseLatestVersionUpdated(log types.Log) (*TeleporterRegistryLatestVersionUpdated, error) { + event := new(TeleporterRegistryLatestVersionUpdated) + if err := _TeleporterRegistry.contract.UnpackLog(event, "LatestVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/teleporter/registry/TeleporterRegistry/packing.go b/abi-bindings/go/teleporter/registry/TeleporterRegistry/packing.go new file mode 100644 index 000000000..a9c31a13f --- /dev/null +++ b/abi-bindings/go/teleporter/registry/TeleporterRegistry/packing.go @@ -0,0 +1,116 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package teleporterregistry + +import ( + "fmt" + + "github.com/ava-labs/libevm/accounts/abi" + "github.com/ava-labs/libevm/common" + "github.com/pkg/errors" +) + +var protocolRegistryEntryType abi.Type +var addressType abi.Type + +func init() { + // Create an ABI binding for ProtocolRegistryEntry, defined in TeleporterRegistry.sol + // abigen does not support ABI bindings for standalone structs, only methods and events, + // so we must manually keep this up-to-date with the struct defined in the contract. + var err error + protocolRegistryEntryType, err = abi.NewType("tuple", "struct Overloader.F", []abi.ArgumentMarshaling{ + {Name: "version", Type: "uint256"}, + {Name: "protocolAddress", Type: "address"}, + }) + if err != nil { + panic(fmt.Sprintf("failed to create ProtocolRegistryEntry ABI type: %v", err)) + } + + addressType, err = abi.NewType("address", "", nil) + if err != nil { + panic(fmt.Sprintf("failed to create address ABI type: %v", err)) + } +} + +// ProtocolRegistryEntry is currently only packed together with the destinationAddress +// in the TeleporterRegistryWarpPayload struct. We still implement the ABIPacker interface for exhaustiveness testing. + +func (p *ProtocolRegistryEntry) Pack() ([]byte, error) { + args := abi.Arguments{ + { + Name: "protocolRegistryEntry", + Type: protocolRegistryEntryType, + }, + } + return args.Pack(p) +} + +func (p *ProtocolRegistryEntry) Unpack(b []byte) error { + args := abi.Arguments{ + { + Name: "protocolRegistryEntry", + Type: protocolRegistryEntryType, + }, + } + unpacked, err := args.Unpack(b) + if err != nil { + return fmt.Errorf("failed to unpack to Teleporter registry entry with err: %v", err) + } + + return args.Copy(&p, unpacked) +} + +func PackTeleporterRegistryWarpPayload(entry ProtocolRegistryEntry, destinationAddress common.Address) ([]byte, error) { + args := abi.Arguments{ + { + Name: "protocolRegistryEntry", + Type: protocolRegistryEntryType, + }, + { + Name: "destinationAddress", + Type: addressType, + }, + } + return args.Pack(entry, destinationAddress) +} + +func UnpackTeleporterRegistryWarpPayload(entryBytes []byte) (ProtocolRegistryEntry, common.Address, error) { + args := abi.Arguments{ + { + Name: "protocolRegistryEntry", + Type: protocolRegistryEntryType, + }, + { + Name: "destinationAddress", + Type: addressType, + }, + } + unpacked, err := args.Unpack(entryBytes) + fmt.Println("unpacked: ", unpacked) + if err != nil { + return ProtocolRegistryEntry{}, common.Address{}, + fmt.Errorf("failed to unpack to Teleporter registry entry with err: %v", err) + } + type teleporterRegistryWarpPayload struct { + ProtocolRegistryEntry ProtocolRegistryEntry `json:"protocolRegistryEntry"` + DestinationAddress common.Address `json:"destinationAddress"` + } + var payload teleporterRegistryWarpPayload + err = args.Copy(&payload, unpacked) + if err != nil { + return ProtocolRegistryEntry{}, common.Address{}, err + } + + return payload.ProtocolRegistryEntry, payload.DestinationAddress, nil +} + +// PackAddProtocolVersion packs input to form a call to the addProtocolVersion function +func PackAddProtocolVersion(messageIndex uint32) ([]byte, error) { + abi, err := TeleporterRegistryMetaData.GetAbi() + if err != nil { + return nil, errors.Wrap(err, "failed to get abi") + } + + return abi.Pack("addProtocolVersion", messageIndex) +} diff --git a/abi-bindings/go/teleporter/registry/TeleporterRegistry/packing_test.go b/abi-bindings/go/teleporter/registry/TeleporterRegistry/packing_test.go new file mode 100644 index 000000000..59930924b --- /dev/null +++ b/abi-bindings/go/teleporter/registry/TeleporterRegistry/packing_test.go @@ -0,0 +1,41 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package teleporterregistry + +import ( + "math/big" + "testing" + + "github.com/ava-labs/libevm/common" + "github.com/stretchr/testify/require" +) + +func TestPackUnpackProtocolRegistryEntry(t *testing.T) { + entry := ProtocolRegistryEntry{ + Version: big.NewInt(1), + ProtocolAddress: common.HexToAddress("0x0123456789abcdef0123456789abcdef01234567"), + } + e, err := entry.Pack() + require.NoError(t, err) + + d := ProtocolRegistryEntry{} + err = d.Unpack(e) + require.NoError(t, err) + require.Equal(t, entry, d) + + destinationAddress := common.HexToAddress("0x0123456789abcdef0123456789abcdef01234568") + + b, err := PackTeleporterRegistryWarpPayload(entry, destinationAddress) + require.NoError(t, err) + + // Confirm that packing of the TeleporterRegistryWarpPayload is prefixed with the ProtocolRegistryEntry packed bytes. + require.Equal(t, e, b[:len(e)]) + + unpackedEntry, unpackedDestinationAddress, err := UnpackTeleporterRegistryWarpPayload(b) + require.NoError(t, err) + + require.Equal(t, entry.Version, unpackedEntry.Version) + require.Equal(t, entry.ProtocolAddress, unpackedEntry.ProtocolAddress) + require.Equal(t, destinationAddress, unpackedDestinationAddress) +} diff --git a/abi-bindings/go/teleporter/tests/TestMessenger/TestMessenger.go b/abi-bindings/go/teleporter/tests/TestMessenger/TestMessenger.go new file mode 100644 index 000000000..d729ced0c --- /dev/null +++ b/abi-bindings/go/teleporter/tests/TestMessenger/TestMessenger.go @@ -0,0 +1,1545 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package testmessenger + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TestMessengerMetaData contains all meta data concerning the TestMessenger contract. +var TestMessengerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReceiveMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"SendMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getCurrentMessage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"sendMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b50604051611ff4380380611ff483398101604081905261002e9161062e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f811580156100775750825b90505f826001600160401b031660011480156100925750303b155b9050811580156100a0575080155b156100be5760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b031916600117855583156100ec57845460ff60401b1916680100000000000000001785555b6100f4610152565b6100ff888888610164565b831561014557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505061067e565b61015a610184565b6101626101d2565b565b61016c610184565b6101768382610200565b61017f82610226565b505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff1661016257604051631afcd79f60e31b815260040160405180910390fd5b6101da610184565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b610208610184565b610210610152565b61021861023a565b6102228282610242565b5050565b61022e610184565b610237816103d1565b50565b610162610184565b61024a610184565b6001600160a01b0382166102cb5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084015b60405180910390fd5b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610330573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103549190610667565b116103a95760405162461bcd60e51b815260206004820152603260248201525f80516020611fd4833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016102c2565b81546001600160a01b0319166001600160a01b0382161782556103cb8361040b565b50505050565b6103d9610184565b6001600160a01b03811661040257604051631e4fbdf760e01b81525f60048201526024016102c2565b610237816105a3565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104969190610667565b6002830154909150818411156104f55760405162461bcd60e51b815260206004820152603160248201525f80516020611fd483398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016102c2565b80841161056a5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016102c2565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b80516001600160a01b0381168114610629575f80fd5b919050565b5f805f60608486031215610640575f80fd5b61064984610613565b925061065760208501610613565b9150604084015190509250925092565b5f60208284031215610677575f80fd5b5051919050565b6119498061068b5f395ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063973142971161006e5780639731429714610159578063b33fead41461017c578063c868efaa1461019d578063d2cc7a70146101b0578063f2fde38b146101d7578063f63d09d7146101ea575f80fd5b80632b0d8f18146100b55780634511243e146100ca5780635eb99514146100dd578063715018a6146100f05780638da5cb5b146100f8578063909a6ac014610137575b5f80fd5b6100c86100c336600461130a565b6101fd565b005b6100c86100d836600461130a565b6102ff565b6100c86100eb366004611325565b6103ee565b6100c8610402565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546040516001600160a01b0390911681526020015b60405180910390f35b61014b5f805160206118f483398151915281565b60405190815260200161012e565b61016c61016736600461130a565b610415565b604051901515815260200161012e565b61018f61018a366004611325565b610435565b60405161012e929190611389565b6100c86101ab3660046113f9565b610507565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d025461014b565b6100c86101e536600461130a565b6106e5565b61014b6101f8366004611451565b61071f565b5f805160206118f483398151915261021361087b565b6001600160a01b0382166102425760405162461bcd60e51b8152600401610239906114d1565b60405180910390fd5b61024c8183610883565b156102af5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b6064820152608401610239565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b5f805160206118f483398151915261031561087b565b6001600160a01b03821661033b5760405162461bcd60e51b8152600401610239906114d1565b6103458183610883565b6103a35760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b6064820152608401610239565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b6103f661087b565b6103ff816108a7565b50565b61040a610a3f565b6104135f610a9a565b565b5f5f805160206118f483398151915261042e8184610883565b9392505050565b5f81815260208181526040808320815180830190925280546001600160a01b0316825260018101805460609486949392908401916104729061151f565b80601f016020809104026020016040519081016040528092919081815260200182805461049e9061151f565b80156104e95780601f106104c0576101008083540402835291602001916104e9565b820191905f5260205f20905b8154815290600101906020018083116104cc57829003601f168201915b5050505050815250509050805f015181602001519250925050915091565b61050f610b0a565b5f5f805160206118f483398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561057a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059e9190611557565b10156106055760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b6064820152608401610239565b61060f8133610883565b156106755760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b6064820152608401610239565b6106b5858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610b5492505050565b506106df60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50505050565b6106ed610a3f565b6001600160a01b03811661071657604051631e4fbdf760e01b81525f6004820152602401610239565b6103ff81610a9a565b5f610728610b0a565b5f851561073c576107398787610c09565b90505b876001600160a01b0316897fa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca898489898960405161077e959493929190611596565b60405180910390a36108446040518060c001604052808b81526020018a6001600160a01b0316815260200160405180604001604052808b6001600160a01b031681526020018581525081526020018781526020015f67ffffffffffffffff8111156107eb576107eb6115c3565b604051908082528060200260200182016040528015610814578160200160208202803683370190505b508152602001868660405160200161082d9291906115d7565b604051602081830303815290604052815250610c15565b91505061087060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b979650505050505050565b610413610a3f565b6001600160a01b0381165f90815260018301602052604090205460ff165b92915050565b5f805160206118f483398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa1580156108fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061091f9190611557565b6002830154909150818411156109915760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b6064820152608401610239565b808411610a065760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e006064820152608401610239565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b33610a717f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146104135760405163118cdaa760e01b8152336004820152602401610239565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00805460011901610b4e57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f81806020019051810190610b6991906115ea565b6040805180820182526001600160a01b03868116825260208083018581525f8a815291829052939020825181546001600160a01b03191692169190911781559151929350916001820190610bbd90826116d2565b50905050826001600160a01b0316847f1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa83604051610bfb9190611792565b60405180910390a350505050565b5f61042e833384610d30565b5f80610c1f610e93565b60408401516020015190915015610cc4576040830151516001600160a01b0316610ca15760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b6064820152608401610239565b604083015160208101519051610cc4916001600160a01b03909116908390610f83565b604051630624488560e41b81526001600160a01b03821690636244885090610cf09086906004016117e7565b6020604051808303815f875af1158015610d0c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042e9190611557565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa158015610d76573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d9a9190611557565b9050610db16001600160a01b03861685308661100a565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015610df5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e199190611557565b9050818111610e7f5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610239565b610e898282611878565b9695505050505050565b5f805160206118f483398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015610eed573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f11919061188b565b9050610f1d8282610883565b156108a15760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b6064820152608401610239565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015610fd0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ff49190611557565b90506106df848461100585856118a6565b611071565b6040516001600160a01b0384811660248301528381166044830152606482018390526106df9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506110fc565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526110c28482611162565b6106df576040516001600160a01b0384811660248301525f60448301526110f691869182169063095ea7b39060640161103f565b6106df84825b5f6111106001600160a01b03841683611203565b905080515f1415801561113457508080602001905181019061113291906118b9565b155b1561115d57604051635274afe760e01b81526001600160a01b0384166004820152602401610239565b505050565b5f805f846001600160a01b03168460405161117d91906118d8565b5f604051808303815f865af19150503d805f81146111b6576040519150601f19603f3d011682016040523d82523d5f602084013e6111bb565b606091505b50915091508180156111e55750805115806111e55750808060200190518101906111e591906118b9565b80156111fa57505f856001600160a01b03163b115b95945050505050565b606061042e83835f845f80856001600160a01b0316848660405161122791906118d8565b5f6040518083038185875af1925050503d805f8114611261576040519150601f19603f3d011682016040523d82523d5f602084013e611266565b606091505b5091509150610e8986838360608261128657611281826112cd565b61042e565b815115801561129d57506001600160a01b0384163b155b156112c657604051639996b31560e01b81526001600160a01b0385166004820152602401610239565b508061042e565b8051156112dd5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b03811681146103ff575f80fd5b5f6020828403121561131a575f80fd5b813561042e816112f6565b5f60208284031215611335575f80fd5b5035919050565b5f5b8381101561135657818101518382015260200161133e565b50505f910152565b5f815180845261137581602086016020860161133c565b601f01601f19169290920160200192915050565b6001600160a01b03831681526040602082018190525f906113ac9083018461135e565b949350505050565b5f8083601f8401126113c4575f80fd5b50813567ffffffffffffffff8111156113db575f80fd5b6020830191508360208285010111156113f2575f80fd5b9250929050565b5f805f806060858703121561140c575f80fd5b84359350602085013561141e816112f6565b9250604085013567ffffffffffffffff811115611439575f80fd5b611445878288016113b4565b95989497509550505050565b5f805f805f805f60c0888a031215611467575f80fd5b873596506020880135611479816112f6565b95506040880135611489816112f6565b9450606088013593506080880135925060a088013567ffffffffffffffff8111156114b2575f80fd5b6114be8a828b016113b4565b989b979a50959850939692959293505050565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b600181811c9082168061153357607f821691505b60208210810361155157634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215611567575f80fd5b5051919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60018060a01b0386168152846020820152836040820152608060608201525f61087060808301848661156e565b634e487b7160e01b5f52604160045260245ffd5b602081525f6113ac60208301848661156e565b5f602082840312156115fa575f80fd5b815167ffffffffffffffff80821115611611575f80fd5b818401915084601f830112611624575f80fd5b815181811115611636576116366115c3565b604051601f8201601f19908116603f0116810190838211818310171561165e5761165e6115c3565b81604052828152876020848701011115611676575f80fd5b61087083602083016020880161133c565b601f82111561115d57805f5260205f20601f840160051c810160208510156116ac5750805b601f840160051c820191505b818110156116cb575f81556001016116b8565b5050505050565b815167ffffffffffffffff8111156116ec576116ec6115c3565b611700816116fa845461151f565b84611687565b602080601f831160018114611733575f841561171c5750858301515b5f19600386901b1c1916600185901b17855561178a565b5f85815260208120601f198616915b8281101561176157888601518255948401946001909101908401611742565b508582101561177e57878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b602081525f61042e602083018461135e565b5f815180845260208085019450602084015f5b838110156117dc5781516001600160a01b0316875295820195908201906001016117b7565b509495945050505050565b60208152815160208201525f602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c08401526118476101008401826117a4565b905060a0840151601f198483030160e08501526111fa828261135e565b634e487b7160e01b5f52601160045260245ffd5b818103818111156108a1576108a1611864565b5f6020828403121561189b575f80fd5b815161042e816112f6565b808201808211156108a1576108a1611864565b5f602082840312156118c9575f80fd5b8151801515811461042e575f80fd5b5f82516118e981846020870161133c565b919091019291505056fede77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a26469706673582212201e0f642dddad9e46400f0aa632e13338481d98c2a8cf023c714fba53d646f75264736f6c6343000819003354656c65706f7274657252656769737472794170703a20696e76616c69642054", +} + +// TestMessengerABI is the input ABI used to generate the binding from. +// Deprecated: Use TestMessengerMetaData.ABI instead. +var TestMessengerABI = TestMessengerMetaData.ABI + +// TestMessengerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TestMessengerMetaData.Bin instead. +var TestMessengerBin = TestMessengerMetaData.Bin + +// DeployTestMessenger deploys a new Ethereum contract, binding an instance of TestMessenger to it. +func DeployTestMessenger(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int) (common.Address, *types.Transaction, *TestMessenger, error) { + parsed, err := TestMessengerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TestMessengerBin), backend, teleporterRegistryAddress, teleporterManager, minTeleporterVersion) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TestMessenger{TestMessengerCaller: TestMessengerCaller{contract: contract}, TestMessengerTransactor: TestMessengerTransactor{contract: contract}, TestMessengerFilterer: TestMessengerFilterer{contract: contract}}, nil +} + +// TestMessenger is an auto generated Go binding around an Ethereum contract. +type TestMessenger struct { + TestMessengerCaller // Read-only binding to the contract + TestMessengerTransactor // Write-only binding to the contract + TestMessengerFilterer // Log filterer for contract events +} + +// TestMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. +type TestMessengerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TestMessengerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TestMessengerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TestMessengerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TestMessengerSession struct { + Contract *TestMessenger // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TestMessengerCallerSession struct { + Contract *TestMessengerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TestMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TestMessengerTransactorSession struct { + Contract *TestMessengerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TestMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. +type TestMessengerRaw struct { + Contract *TestMessenger // Generic contract binding to access the raw methods on +} + +// TestMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TestMessengerCallerRaw struct { + Contract *TestMessengerCaller // Generic read-only contract binding to access the raw methods on +} + +// TestMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TestMessengerTransactorRaw struct { + Contract *TestMessengerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTestMessenger creates a new instance of TestMessenger, bound to a specific deployed contract. +func NewTestMessenger(address common.Address, backend bind.ContractBackend) (*TestMessenger, error) { + contract, err := bindTestMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TestMessenger{TestMessengerCaller: TestMessengerCaller{contract: contract}, TestMessengerTransactor: TestMessengerTransactor{contract: contract}, TestMessengerFilterer: TestMessengerFilterer{contract: contract}}, nil +} + +// NewTestMessengerCaller creates a new read-only instance of TestMessenger, bound to a specific deployed contract. +func NewTestMessengerCaller(address common.Address, caller bind.ContractCaller) (*TestMessengerCaller, error) { + contract, err := bindTestMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TestMessengerCaller{contract: contract}, nil +} + +// NewTestMessengerTransactor creates a new write-only instance of TestMessenger, bound to a specific deployed contract. +func NewTestMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*TestMessengerTransactor, error) { + contract, err := bindTestMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TestMessengerTransactor{contract: contract}, nil +} + +// NewTestMessengerFilterer creates a new log filterer instance of TestMessenger, bound to a specific deployed contract. +func NewTestMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*TestMessengerFilterer, error) { + contract, err := bindTestMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TestMessengerFilterer{contract: contract}, nil +} + +// bindTestMessenger binds a generic wrapper to an already deployed contract. +func bindTestMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TestMessengerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TestMessenger *TestMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestMessenger.Contract.TestMessengerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TestMessenger *TestMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestMessenger.Contract.TestMessengerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestMessenger *TestMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestMessenger.Contract.TestMessengerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TestMessenger *TestMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TestMessenger.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TestMessenger *TestMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestMessenger.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TestMessenger *TestMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TestMessenger.Contract.contract.Transact(opts, method, params...) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TestMessenger *TestMessengerCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _TestMessenger.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TestMessenger *TestMessengerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _TestMessenger.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_TestMessenger.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_TestMessenger *TestMessengerCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _TestMessenger.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_TestMessenger.CallOpts) +} + +// GetCurrentMessage is a free data retrieval call binding the contract method 0xb33fead4. +// +// Solidity: function getCurrentMessage(bytes32 sourceBlockchainID) view returns(address, string) +func (_TestMessenger *TestMessengerCaller) GetCurrentMessage(opts *bind.CallOpts, sourceBlockchainID [32]byte) (common.Address, string, error) { + var out []interface{} + err := _TestMessenger.contract.Call(opts, &out, "getCurrentMessage", sourceBlockchainID) + + if err != nil { + return *new(common.Address), *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(string)).(*string) + + return out0, out1, err + +} + +// GetCurrentMessage is a free data retrieval call binding the contract method 0xb33fead4. +// +// Solidity: function getCurrentMessage(bytes32 sourceBlockchainID) view returns(address, string) +func (_TestMessenger *TestMessengerSession) GetCurrentMessage(sourceBlockchainID [32]byte) (common.Address, string, error) { + return _TestMessenger.Contract.GetCurrentMessage(&_TestMessenger.CallOpts, sourceBlockchainID) +} + +// GetCurrentMessage is a free data retrieval call binding the contract method 0xb33fead4. +// +// Solidity: function getCurrentMessage(bytes32 sourceBlockchainID) view returns(address, string) +func (_TestMessenger *TestMessengerCallerSession) GetCurrentMessage(sourceBlockchainID [32]byte) (common.Address, string, error) { + return _TestMessenger.Contract.GetCurrentMessage(&_TestMessenger.CallOpts, sourceBlockchainID) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TestMessenger *TestMessengerCaller) GetMinTeleporterVersion(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _TestMessenger.contract.Call(opts, &out, "getMinTeleporterVersion") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TestMessenger *TestMessengerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _TestMessenger.Contract.GetMinTeleporterVersion(&_TestMessenger.CallOpts) +} + +// GetMinTeleporterVersion is a free data retrieval call binding the contract method 0xd2cc7a70. +// +// Solidity: function getMinTeleporterVersion() view returns(uint256) +func (_TestMessenger *TestMessengerCallerSession) GetMinTeleporterVersion() (*big.Int, error) { + return _TestMessenger.Contract.GetMinTeleporterVersion(&_TestMessenger.CallOpts) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TestMessenger *TestMessengerCaller) IsTeleporterAddressPaused(opts *bind.CallOpts, teleporterAddress common.Address) (bool, error) { + var out []interface{} + err := _TestMessenger.contract.Call(opts, &out, "isTeleporterAddressPaused", teleporterAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TestMessenger *TestMessengerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _TestMessenger.Contract.IsTeleporterAddressPaused(&_TestMessenger.CallOpts, teleporterAddress) +} + +// IsTeleporterAddressPaused is a free data retrieval call binding the contract method 0x97314297. +// +// Solidity: function isTeleporterAddressPaused(address teleporterAddress) view returns(bool) +func (_TestMessenger *TestMessengerCallerSession) IsTeleporterAddressPaused(teleporterAddress common.Address) (bool, error) { + return _TestMessenger.Contract.IsTeleporterAddressPaused(&_TestMessenger.CallOpts, teleporterAddress) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TestMessenger *TestMessengerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TestMessenger.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TestMessenger *TestMessengerSession) Owner() (common.Address, error) { + return _TestMessenger.Contract.Owner(&_TestMessenger.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TestMessenger *TestMessengerCallerSession) Owner() (common.Address, error) { + return _TestMessenger.Contract.Owner(&_TestMessenger.CallOpts) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TestMessenger *TestMessengerTransactor) PauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _TestMessenger.contract.Transact(opts, "pauseTeleporterAddress", teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TestMessenger *TestMessengerSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TestMessenger.Contract.PauseTeleporterAddress(&_TestMessenger.TransactOpts, teleporterAddress) +} + +// PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. +// +// Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() +func (_TestMessenger *TestMessengerTransactorSession) PauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TestMessenger.Contract.PauseTeleporterAddress(&_TestMessenger.TransactOpts, teleporterAddress) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TestMessenger *TestMessengerTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TestMessenger.contract.Transact(opts, "receiveTeleporterMessage", sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TestMessenger *TestMessengerSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TestMessenger.Contract.ReceiveTeleporterMessage(&_TestMessenger.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 sourceBlockchainID, address originSenderAddress, bytes message) returns() +func (_TestMessenger *TestMessengerTransactorSession) ReceiveTeleporterMessage(sourceBlockchainID [32]byte, originSenderAddress common.Address, message []byte) (*types.Transaction, error) { + return _TestMessenger.Contract.ReceiveTeleporterMessage(&_TestMessenger.TransactOpts, sourceBlockchainID, originSenderAddress, message) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TestMessenger *TestMessengerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TestMessenger.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TestMessenger *TestMessengerSession) RenounceOwnership() (*types.Transaction, error) { + return _TestMessenger.Contract.RenounceOwnership(&_TestMessenger.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_TestMessenger *TestMessengerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _TestMessenger.Contract.RenounceOwnership(&_TestMessenger.TransactOpts) +} + +// SendMessage is a paid mutator transaction binding the contract method 0xf63d09d7. +// +// Solidity: function sendMessage(bytes32 destinationBlockchainID, address destinationAddress, address feeTokenAddress, uint256 feeAmount, uint256 requiredGasLimit, string message) returns(bytes32) +func (_TestMessenger *TestMessengerTransactor) SendMessage(opts *bind.TransactOpts, destinationBlockchainID [32]byte, destinationAddress common.Address, feeTokenAddress common.Address, feeAmount *big.Int, requiredGasLimit *big.Int, message string) (*types.Transaction, error) { + return _TestMessenger.contract.Transact(opts, "sendMessage", destinationBlockchainID, destinationAddress, feeTokenAddress, feeAmount, requiredGasLimit, message) +} + +// SendMessage is a paid mutator transaction binding the contract method 0xf63d09d7. +// +// Solidity: function sendMessage(bytes32 destinationBlockchainID, address destinationAddress, address feeTokenAddress, uint256 feeAmount, uint256 requiredGasLimit, string message) returns(bytes32) +func (_TestMessenger *TestMessengerSession) SendMessage(destinationBlockchainID [32]byte, destinationAddress common.Address, feeTokenAddress common.Address, feeAmount *big.Int, requiredGasLimit *big.Int, message string) (*types.Transaction, error) { + return _TestMessenger.Contract.SendMessage(&_TestMessenger.TransactOpts, destinationBlockchainID, destinationAddress, feeTokenAddress, feeAmount, requiredGasLimit, message) +} + +// SendMessage is a paid mutator transaction binding the contract method 0xf63d09d7. +// +// Solidity: function sendMessage(bytes32 destinationBlockchainID, address destinationAddress, address feeTokenAddress, uint256 feeAmount, uint256 requiredGasLimit, string message) returns(bytes32) +func (_TestMessenger *TestMessengerTransactorSession) SendMessage(destinationBlockchainID [32]byte, destinationAddress common.Address, feeTokenAddress common.Address, feeAmount *big.Int, requiredGasLimit *big.Int, message string) (*types.Transaction, error) { + return _TestMessenger.Contract.SendMessage(&_TestMessenger.TransactOpts, destinationBlockchainID, destinationAddress, feeTokenAddress, feeAmount, requiredGasLimit, message) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TestMessenger *TestMessengerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TestMessenger.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TestMessenger *TestMessengerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TestMessenger.Contract.TransferOwnership(&_TestMessenger.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TestMessenger *TestMessengerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TestMessenger.Contract.TransferOwnership(&_TestMessenger.TransactOpts, newOwner) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TestMessenger *TestMessengerTransactor) UnpauseTeleporterAddress(opts *bind.TransactOpts, teleporterAddress common.Address) (*types.Transaction, error) { + return _TestMessenger.contract.Transact(opts, "unpauseTeleporterAddress", teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TestMessenger *TestMessengerSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TestMessenger.Contract.UnpauseTeleporterAddress(&_TestMessenger.TransactOpts, teleporterAddress) +} + +// UnpauseTeleporterAddress is a paid mutator transaction binding the contract method 0x4511243e. +// +// Solidity: function unpauseTeleporterAddress(address teleporterAddress) returns() +func (_TestMessenger *TestMessengerTransactorSession) UnpauseTeleporterAddress(teleporterAddress common.Address) (*types.Transaction, error) { + return _TestMessenger.Contract.UnpauseTeleporterAddress(&_TestMessenger.TransactOpts, teleporterAddress) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TestMessenger *TestMessengerTransactor) UpdateMinTeleporterVersion(opts *bind.TransactOpts, version *big.Int) (*types.Transaction, error) { + return _TestMessenger.contract.Transact(opts, "updateMinTeleporterVersion", version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TestMessenger *TestMessengerSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _TestMessenger.Contract.UpdateMinTeleporterVersion(&_TestMessenger.TransactOpts, version) +} + +// UpdateMinTeleporterVersion is a paid mutator transaction binding the contract method 0x5eb99514. +// +// Solidity: function updateMinTeleporterVersion(uint256 version) returns() +func (_TestMessenger *TestMessengerTransactorSession) UpdateMinTeleporterVersion(version *big.Int) (*types.Transaction, error) { + return _TestMessenger.Contract.UpdateMinTeleporterVersion(&_TestMessenger.TransactOpts, version) +} + +// TestMessengerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the TestMessenger contract. +type TestMessengerInitializedIterator struct { + Event *TestMessengerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestMessengerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestMessengerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestMessengerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestMessengerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestMessengerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestMessengerInitialized represents a Initialized event raised by the TestMessenger contract. +type TestMessengerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TestMessenger *TestMessengerFilterer) FilterInitialized(opts *bind.FilterOpts) (*TestMessengerInitializedIterator, error) { + + logs, sub, err := _TestMessenger.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &TestMessengerInitializedIterator{contract: _TestMessenger.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TestMessenger *TestMessengerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *TestMessengerInitialized) (event.Subscription, error) { + + logs, sub, err := _TestMessenger.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestMessengerInitialized) + if err := _TestMessenger.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_TestMessenger *TestMessengerFilterer) ParseInitialized(log types.Log) (*TestMessengerInitialized, error) { + event := new(TestMessengerInitialized) + if err := _TestMessenger.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestMessengerMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the TestMessenger contract. +type TestMessengerMinTeleporterVersionUpdatedIterator struct { + Event *TestMessengerMinTeleporterVersionUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestMessengerMinTeleporterVersionUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestMessengerMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestMessengerMinTeleporterVersionUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestMessengerMinTeleporterVersionUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestMessengerMinTeleporterVersionUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestMessengerMinTeleporterVersionUpdated represents a MinTeleporterVersionUpdated event raised by the TestMessenger contract. +type TestMessengerMinTeleporterVersionUpdated struct { + OldMinTeleporterVersion *big.Int + NewMinTeleporterVersion *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMinTeleporterVersionUpdated is a free log retrieval operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TestMessenger *TestMessengerFilterer) FilterMinTeleporterVersionUpdated(opts *bind.FilterOpts, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (*TestMessengerMinTeleporterVersionUpdatedIterator, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _TestMessenger.contract.FilterLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return &TestMessengerMinTeleporterVersionUpdatedIterator{contract: _TestMessenger.contract, event: "MinTeleporterVersionUpdated", logs: logs, sub: sub}, nil +} + +// WatchMinTeleporterVersionUpdated is a free log subscription operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TestMessenger *TestMessengerFilterer) WatchMinTeleporterVersionUpdated(opts *bind.WatchOpts, sink chan<- *TestMessengerMinTeleporterVersionUpdated, oldMinTeleporterVersion []*big.Int, newMinTeleporterVersion []*big.Int) (event.Subscription, error) { + + var oldMinTeleporterVersionRule []interface{} + for _, oldMinTeleporterVersionItem := range oldMinTeleporterVersion { + oldMinTeleporterVersionRule = append(oldMinTeleporterVersionRule, oldMinTeleporterVersionItem) + } + var newMinTeleporterVersionRule []interface{} + for _, newMinTeleporterVersionItem := range newMinTeleporterVersion { + newMinTeleporterVersionRule = append(newMinTeleporterVersionRule, newMinTeleporterVersionItem) + } + + logs, sub, err := _TestMessenger.contract.WatchLogs(opts, "MinTeleporterVersionUpdated", oldMinTeleporterVersionRule, newMinTeleporterVersionRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestMessengerMinTeleporterVersionUpdated) + if err := _TestMessenger.contract.UnpackLog(event, "MinTeleporterVersionUpdated", 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 +} + +// ParseMinTeleporterVersionUpdated is a log parse operation binding the contract event 0xa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d. +// +// Solidity: event MinTeleporterVersionUpdated(uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion) +func (_TestMessenger *TestMessengerFilterer) ParseMinTeleporterVersionUpdated(log types.Log) (*TestMessengerMinTeleporterVersionUpdated, error) { + event := new(TestMessengerMinTeleporterVersionUpdated) + if err := _TestMessenger.contract.UnpackLog(event, "MinTeleporterVersionUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestMessengerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TestMessenger contract. +type TestMessengerOwnershipTransferredIterator struct { + Event *TestMessengerOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestMessengerOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestMessengerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestMessengerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestMessengerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestMessengerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestMessengerOwnershipTransferred represents a OwnershipTransferred event raised by the TestMessenger contract. +type TestMessengerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TestMessenger *TestMessengerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TestMessengerOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TestMessenger.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TestMessengerOwnershipTransferredIterator{contract: _TestMessenger.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TestMessenger *TestMessengerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TestMessengerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TestMessenger.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestMessengerOwnershipTransferred) + if err := _TestMessenger.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TestMessenger *TestMessengerFilterer) ParseOwnershipTransferred(log types.Log) (*TestMessengerOwnershipTransferred, error) { + event := new(TestMessengerOwnershipTransferred) + if err := _TestMessenger.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestMessengerReceiveMessageIterator is returned from FilterReceiveMessage and is used to iterate over the raw logs and unpacked data for ReceiveMessage events raised by the TestMessenger contract. +type TestMessengerReceiveMessageIterator struct { + Event *TestMessengerReceiveMessage // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestMessengerReceiveMessageIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestMessengerReceiveMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestMessengerReceiveMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestMessengerReceiveMessageIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestMessengerReceiveMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestMessengerReceiveMessage represents a ReceiveMessage event raised by the TestMessenger contract. +type TestMessengerReceiveMessage struct { + SourceBlockchainID [32]byte + OriginSenderAddress common.Address + Message string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterReceiveMessage is a free log retrieval operation binding the contract event 0x1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa. +// +// Solidity: event ReceiveMessage(bytes32 indexed sourceBlockchainID, address indexed originSenderAddress, string message) +func (_TestMessenger *TestMessengerFilterer) FilterReceiveMessage(opts *bind.FilterOpts, sourceBlockchainID [][32]byte, originSenderAddress []common.Address) (*TestMessengerReceiveMessageIterator, error) { + + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var originSenderAddressRule []interface{} + for _, originSenderAddressItem := range originSenderAddress { + originSenderAddressRule = append(originSenderAddressRule, originSenderAddressItem) + } + + logs, sub, err := _TestMessenger.contract.FilterLogs(opts, "ReceiveMessage", sourceBlockchainIDRule, originSenderAddressRule) + if err != nil { + return nil, err + } + return &TestMessengerReceiveMessageIterator{contract: _TestMessenger.contract, event: "ReceiveMessage", logs: logs, sub: sub}, nil +} + +// WatchReceiveMessage is a free log subscription operation binding the contract event 0x1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa. +// +// Solidity: event ReceiveMessage(bytes32 indexed sourceBlockchainID, address indexed originSenderAddress, string message) +func (_TestMessenger *TestMessengerFilterer) WatchReceiveMessage(opts *bind.WatchOpts, sink chan<- *TestMessengerReceiveMessage, sourceBlockchainID [][32]byte, originSenderAddress []common.Address) (event.Subscription, error) { + + var sourceBlockchainIDRule []interface{} + for _, sourceBlockchainIDItem := range sourceBlockchainID { + sourceBlockchainIDRule = append(sourceBlockchainIDRule, sourceBlockchainIDItem) + } + var originSenderAddressRule []interface{} + for _, originSenderAddressItem := range originSenderAddress { + originSenderAddressRule = append(originSenderAddressRule, originSenderAddressItem) + } + + logs, sub, err := _TestMessenger.contract.WatchLogs(opts, "ReceiveMessage", sourceBlockchainIDRule, originSenderAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestMessengerReceiveMessage) + if err := _TestMessenger.contract.UnpackLog(event, "ReceiveMessage", 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 +} + +// ParseReceiveMessage is a log parse operation binding the contract event 0x1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa. +// +// Solidity: event ReceiveMessage(bytes32 indexed sourceBlockchainID, address indexed originSenderAddress, string message) +func (_TestMessenger *TestMessengerFilterer) ParseReceiveMessage(log types.Log) (*TestMessengerReceiveMessage, error) { + event := new(TestMessengerReceiveMessage) + if err := _TestMessenger.contract.UnpackLog(event, "ReceiveMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestMessengerSendMessageIterator is returned from FilterSendMessage and is used to iterate over the raw logs and unpacked data for SendMessage events raised by the TestMessenger contract. +type TestMessengerSendMessageIterator struct { + Event *TestMessengerSendMessage // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestMessengerSendMessageIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestMessengerSendMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestMessengerSendMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestMessengerSendMessageIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestMessengerSendMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestMessengerSendMessage represents a SendMessage event raised by the TestMessenger contract. +type TestMessengerSendMessage struct { + DestinationBlockchainID [32]byte + DestinationAddress common.Address + FeeTokenAddress common.Address + FeeAmount *big.Int + RequiredGasLimit *big.Int + Message string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSendMessage is a free log retrieval operation binding the contract event 0xa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca. +// +// Solidity: event SendMessage(bytes32 indexed destinationBlockchainID, address indexed destinationAddress, address feeTokenAddress, uint256 feeAmount, uint256 requiredGasLimit, string message) +func (_TestMessenger *TestMessengerFilterer) FilterSendMessage(opts *bind.FilterOpts, destinationBlockchainID [][32]byte, destinationAddress []common.Address) (*TestMessengerSendMessageIterator, error) { + + var destinationBlockchainIDRule []interface{} + for _, destinationBlockchainIDItem := range destinationBlockchainID { + destinationBlockchainIDRule = append(destinationBlockchainIDRule, destinationBlockchainIDItem) + } + var destinationAddressRule []interface{} + for _, destinationAddressItem := range destinationAddress { + destinationAddressRule = append(destinationAddressRule, destinationAddressItem) + } + + logs, sub, err := _TestMessenger.contract.FilterLogs(opts, "SendMessage", destinationBlockchainIDRule, destinationAddressRule) + if err != nil { + return nil, err + } + return &TestMessengerSendMessageIterator{contract: _TestMessenger.contract, event: "SendMessage", logs: logs, sub: sub}, nil +} + +// WatchSendMessage is a free log subscription operation binding the contract event 0xa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca. +// +// Solidity: event SendMessage(bytes32 indexed destinationBlockchainID, address indexed destinationAddress, address feeTokenAddress, uint256 feeAmount, uint256 requiredGasLimit, string message) +func (_TestMessenger *TestMessengerFilterer) WatchSendMessage(opts *bind.WatchOpts, sink chan<- *TestMessengerSendMessage, destinationBlockchainID [][32]byte, destinationAddress []common.Address) (event.Subscription, error) { + + var destinationBlockchainIDRule []interface{} + for _, destinationBlockchainIDItem := range destinationBlockchainID { + destinationBlockchainIDRule = append(destinationBlockchainIDRule, destinationBlockchainIDItem) + } + var destinationAddressRule []interface{} + for _, destinationAddressItem := range destinationAddress { + destinationAddressRule = append(destinationAddressRule, destinationAddressItem) + } + + logs, sub, err := _TestMessenger.contract.WatchLogs(opts, "SendMessage", destinationBlockchainIDRule, destinationAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestMessengerSendMessage) + if err := _TestMessenger.contract.UnpackLog(event, "SendMessage", 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 +} + +// ParseSendMessage is a log parse operation binding the contract event 0xa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca. +// +// Solidity: event SendMessage(bytes32 indexed destinationBlockchainID, address indexed destinationAddress, address feeTokenAddress, uint256 feeAmount, uint256 requiredGasLimit, string message) +func (_TestMessenger *TestMessengerFilterer) ParseSendMessage(log types.Log) (*TestMessengerSendMessage, error) { + event := new(TestMessengerSendMessage) + if err := _TestMessenger.contract.UnpackLog(event, "SendMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestMessengerTeleporterAddressPausedIterator is returned from FilterTeleporterAddressPaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressPaused events raised by the TestMessenger contract. +type TestMessengerTeleporterAddressPausedIterator struct { + Event *TestMessengerTeleporterAddressPaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestMessengerTeleporterAddressPausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestMessengerTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestMessengerTeleporterAddressPaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestMessengerTeleporterAddressPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestMessengerTeleporterAddressPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestMessengerTeleporterAddressPaused represents a TeleporterAddressPaused event raised by the TestMessenger contract. +type TestMessengerTeleporterAddressPaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressPaused is a free log retrieval operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TestMessenger *TestMessengerFilterer) FilterTeleporterAddressPaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*TestMessengerTeleporterAddressPausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TestMessenger.contract.FilterLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &TestMessengerTeleporterAddressPausedIterator{contract: _TestMessenger.contract, event: "TeleporterAddressPaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressPaused is a free log subscription operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TestMessenger *TestMessengerFilterer) WatchTeleporterAddressPaused(opts *bind.WatchOpts, sink chan<- *TestMessengerTeleporterAddressPaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TestMessenger.contract.WatchLogs(opts, "TeleporterAddressPaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestMessengerTeleporterAddressPaused) + if err := _TestMessenger.contract.UnpackLog(event, "TeleporterAddressPaused", 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 +} + +// ParseTeleporterAddressPaused is a log parse operation binding the contract event 0x933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c. +// +// Solidity: event TeleporterAddressPaused(address indexed teleporterAddress) +func (_TestMessenger *TestMessengerFilterer) ParseTeleporterAddressPaused(log types.Log) (*TestMessengerTeleporterAddressPaused, error) { + event := new(TestMessengerTeleporterAddressPaused) + if err := _TestMessenger.contract.UnpackLog(event, "TeleporterAddressPaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TestMessengerTeleporterAddressUnpausedIterator is returned from FilterTeleporterAddressUnpaused and is used to iterate over the raw logs and unpacked data for TeleporterAddressUnpaused events raised by the TestMessenger contract. +type TestMessengerTeleporterAddressUnpausedIterator struct { + Event *TestMessengerTeleporterAddressUnpaused // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TestMessengerTeleporterAddressUnpausedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TestMessengerTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TestMessengerTeleporterAddressUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TestMessengerTeleporterAddressUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TestMessengerTeleporterAddressUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TestMessengerTeleporterAddressUnpaused represents a TeleporterAddressUnpaused event raised by the TestMessenger contract. +type TestMessengerTeleporterAddressUnpaused struct { + TeleporterAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleporterAddressUnpaused is a free log retrieval operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TestMessenger *TestMessengerFilterer) FilterTeleporterAddressUnpaused(opts *bind.FilterOpts, teleporterAddress []common.Address) (*TestMessengerTeleporterAddressUnpausedIterator, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TestMessenger.contract.FilterLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return &TestMessengerTeleporterAddressUnpausedIterator{contract: _TestMessenger.contract, event: "TeleporterAddressUnpaused", logs: logs, sub: sub}, nil +} + +// WatchTeleporterAddressUnpaused is a free log subscription operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TestMessenger *TestMessengerFilterer) WatchTeleporterAddressUnpaused(opts *bind.WatchOpts, sink chan<- *TestMessengerTeleporterAddressUnpaused, teleporterAddress []common.Address) (event.Subscription, error) { + + var teleporterAddressRule []interface{} + for _, teleporterAddressItem := range teleporterAddress { + teleporterAddressRule = append(teleporterAddressRule, teleporterAddressItem) + } + + logs, sub, err := _TestMessenger.contract.WatchLogs(opts, "TeleporterAddressUnpaused", teleporterAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TestMessengerTeleporterAddressUnpaused) + if err := _TestMessenger.contract.UnpackLog(event, "TeleporterAddressUnpaused", 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 +} + +// ParseTeleporterAddressUnpaused is a log parse operation binding the contract event 0x844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c3. +// +// Solidity: event TeleporterAddressUnpaused(address indexed teleporterAddress) +func (_TestMessenger *TestMessengerFilterer) ParseTeleporterAddressUnpaused(log types.Log) (*TestMessengerTeleporterAddressUnpaused, error) { + event := new(TestMessengerTeleporterAddressUnpaused) + if err := _TestMessenger.contract.UnpackLog(event, "TeleporterAddressUnpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/teleporter/tests/TestMessenger/constants.go b/abi-bindings/go/teleporter/tests/TestMessenger/constants.go new file mode 100644 index 000000000..bb96aaeb2 --- /dev/null +++ b/abi-bindings/go/teleporter/tests/TestMessenger/constants.go @@ -0,0 +1,5 @@ +package testmessenger + +import "math/big" + +var SendMessageRequiredGas = big.NewInt(300000) diff --git a/tests/abi-bindings/go/BatchCrossChainMessenger/BatchCrossChainMessenger.go b/abi-bindings/go/utilities/BatchCrossChainMessenger/BatchCrossChainMessenger.go similarity index 68% rename from tests/abi-bindings/go/BatchCrossChainMessenger/BatchCrossChainMessenger.go rename to abi-bindings/go/utilities/BatchCrossChainMessenger/BatchCrossChainMessenger.go index ddb3cc3fa..73657b8a4 100644 --- a/tests/abi-bindings/go/BatchCrossChainMessenger/BatchCrossChainMessenger.go +++ b/abi-bindings/go/utilities/BatchCrossChainMessenger/BatchCrossChainMessenger.go @@ -31,8 +31,8 @@ var ( // BatchCrossChainMessengerMetaData contains all meta data concerning the BatchCrossChainMessenger contract. var BatchCrossChainMessengerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReceiveMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"messages\",\"type\":\"string[]\"}],\"name\":\"SendMessages\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getCurrentMessages\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"string[]\",\"name\":\"messages\",\"type\":\"string[]\"}],\"name\":\"sendMessages\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleporterRegistry\",\"outputs\":[{\"internalType\":\"contractTeleporterRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162001e7938038062001e7983398101604081905262000034916200029f565b60016000558181816001600160a01b038116620000be5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465725570677261646561626c653a207a65726f2074656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084015b60405180910390fd5b6001600160a01b03811660808190526040805163301fd1f560e21b8152905163c07f47d4916004808201926020929091908290030181865afa15801562000109573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012f9190620002d7565b600255506200013e3362000153565b6200014981620001a5565b50505050620002f1565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001af62000224565b6001600160a01b038116620002165760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401620000b5565b620002218162000153565b50565b6003546001600160a01b03163314620002805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000b5565b565b80516001600160a01b03811681146200029a57600080fd5b919050565b60008060408385031215620002b357600080fd5b620002be8362000282565b9150620002ce6020840162000282565b90509250929050565b600060208284031215620002ea57600080fd5b5051919050565b608051611b58620003216000396000818160be0152818161070401528181610c240152610f660152611b586000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80638da5cb5b116100715780638da5cb5b146101605780639731429714610171578063c1329fcb146101ad578063c868efaa146101cd578063d2cc7a70146101e0578063f2fde38b146101f157600080fd5b80631a7f5bec146100b95780632b0d8f18146100fd5780633902970c146101125780634511243e146101325780635eb9951414610145578063715018a614610158575b600080fd5b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61011061010b3660046113a3565b610204565b005b61012561012036600461142f565b610309565b6040516100f49190611596565b6101106101403660046113a3565b6104e7565b6101106101533660046115da565b6105e4565b6101106105f8565b6003546001600160a01b03166100e0565b61019d61017f3660046113a3565b6001600160a01b031660009081526001602052604090205460ff1690565b60405190151581526020016100f4565b6101c06101bb3660046115da565b61060c565b6040516100f49190611698565b6101106101db3660046116ab565b6106ef565b6002546040519081526020016100f4565b6101106101ff3660046113a3565b6108b9565b61020c61092f565b6001600160a01b03811661023b5760405162461bcd60e51b815260040161023290611734565b60405180910390fd5b6001600160a01b03811660009081526001602052604090205460ff16156102ba5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f727465725570677261646561626c653a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b6064820152608401610232565b6001600160a01b0381166000818152600160208190526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a250565b6060610313610937565b60008415610328576103258686610990565b90505b866001600160a01b0316887f430d1906813fdb2129a19139f4112a1396804605501a798df3a4042590ba20d5888488886040516103689493929190611782565b60405180910390a36000835167ffffffffffffffff81111561038c5761038c6113c0565b6040519080825280602002602001820160405280156103b5578160200160208202803683370190505b50905060005b84518110156104cf57600061049c6040518060c001604052808d81526020018c6001600160a01b0316815260200160405180604001604052808d6001600160a01b03168152602001888152508152602001898152602001600067ffffffffffffffff81111561042c5761042c6113c0565b604051908082528060200260200182016040528015610455578160200160208202803683370190505b50815260200188858151811061046d5761046d6117af565b602002602001015160405160200161048591906117c5565b604051602081830303815290604052815250610afa565b9050808383815181106104b1576104b16117af565b602090810291909101015250806104c7816117ee565b9150506103bb565b509150506104dd6001600055565b9695505050505050565b6104ef61092f565b6001600160a01b0381166105155760405162461bcd60e51b815260040161023290611734565b6001600160a01b03811660009081526001602052604090205460ff1661058f5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465725570677261646561626c653a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b6064820152608401610232565b6040516001600160a01b038216907f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c390600090a26001600160a01b03166000908152600160205260409020805460ff19169055565b6105ec61092f565b6105f581610c20565b50565b610600610dc0565b61060a6000610e1a565b565b6000818152600460209081526040808320805482518185028101850190935280835260609493849084015b828210156106e357838290600052602060002001805461065690611807565b80601f016020809104026020016040519081016040528092919081815260200182805461068290611807565b80156106cf5780601f106106a4576101008083540402835291602001916106cf565b820191906000526020600020905b8154815290600101906020018083116106b257829003601f168201915b505050505081526020019060010190610637565b50929695505050505050565b6106f7610937565b6002546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561076e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107929190611841565b10156107f95760405162461bcd60e51b815260206004820152603060248201527f54656c65706f727465725570677261646561626c653a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b6064820152608401610232565b6108023361017f565b156108685760405162461bcd60e51b815260206004820152603060248201527f54656c65706f727465725570677261646561626c653a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b6064820152608401610232565b6108a9848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e6c92505050565b6108b36001600055565b50505050565b6108c1610dc0565b6001600160a01b0381166109265760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610232565b6105f581610e1a565b61060a610dc0565b6002600054036109895760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610232565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156109d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fd9190611841565b9050610a146001600160a01b038516333086610ef6565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610a5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7f9190611841565b9050818111610ae55760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610232565b610aef828261185a565b925050505b92915050565b600080610b05610f61565b60408401516020015190915015610baa576040830151516001600160a01b0316610b875760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f727465725570677261646561626c653a207a65726f206665652060448201526c746f6b656e206164647265737360981b6064820152608401610232565b604083015160208101519051610baa916001600160a01b03909116908390611075565b604051630624488560e41b81526001600160a01b03821690636244885090610bd69086906004016118b1565b6020604051808303816000875af1158015610bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c199190611841565b9392505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca49190611841565b60025490915081831115610d145760405162461bcd60e51b815260206004820152603160248201527f54656c65706f727465725570677261646561626c653a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b6064820152608401610232565b808311610d895760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f727465725570677261646561626c653a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e006064820152608401610232565b6002839055604051839082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d90600090a3505050565b6003546001600160a01b0316331461060a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610232565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081806020019051810190610e82919061192f565b600085815260046020908152604082208054600181018255908352912091925001610ead82826119f4565b50826001600160a01b0316847f1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa83604051610ee891906117c5565b60405180910390a350505050565b6040516001600160a01b03808516602483015283166044820152606481018290526108b39085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611127565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe69190611ab4565b905061100a816001600160a01b031660009081526001602052604090205460ff1690565b156110705760405162461bcd60e51b815260206004820152603060248201527f54656c65706f727465725570677261646561626c653a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b6064820152608401610232565b919050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156110c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ea9190611841565b6110f49190611ad1565b6040516001600160a01b0385166024820152604481018290529091506108b390859063095ea7b360e01b90606401610f2a565b600061117c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166111fe9092919063ffffffff16565b8051909150156111f9578080602001905181019061119a9190611ae4565b6111f95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610232565b505050565b606061120d8484600085611215565b949350505050565b6060824710156112765760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610232565b600080866001600160a01b031685876040516112929190611b06565b60006040518083038185875af1925050503d80600081146112cf576040519150601f19603f3d011682016040523d82523d6000602084013e6112d4565b606091505b50915091506112e5878383876112f0565b979650505050505050565b6060831561135f578251600003611358576001600160a01b0385163b6113585760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610232565b508161120d565b61120d83838151156113745781518083602001fd5b8060405162461bcd60e51b815260040161023291906117c5565b6001600160a01b03811681146105f557600080fd5b6000602082840312156113b557600080fd5b8135610c198161138e565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156113ff576113ff6113c0565b604052919050565b600067ffffffffffffffff821115611421576114216113c0565b50601f01601f191660200190565b60008060008060008060c0878903121561144857600080fd5b86359550611459602088013561138e565b6020870135945061146d604088013561138e565b60408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561149b57600080fd5b60a0870135870188601f8201126114b157600080fd5b67ffffffffffffffff813511156114ca576114ca6113c0565b6114da6020823560051b016113d6565b81358082526020808301929160051b8401018b8111156114f957600080fd5b602084015b818110156115845767ffffffffffffffff8135111561151c57600080fd5b803585018d603f82011261152f57600080fd5b602081013561154561154082611407565b6113d6565b8181528f604083850101111561155a57600080fd5b816040840160208301376000602083830101528087525050506020840193506020810190506114fe565b50508093505050509295509295509295565b6020808252825182820181905260009190848201906040850190845b818110156115ce578351835292840192918401916001016115b2565b50909695505050505050565b6000602082840312156115ec57600080fd5b5035919050565b60005b8381101561160e5781810151838201526020016115f6565b50506000910152565b6000815180845261162f8160208601602086016115f3565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b8581101561168b578284038952611679848351611617565b98850198935090840190600101611661565b5091979650505050505050565b602081526000610c196020830184611643565b600080600080606085870312156116c157600080fd5b8435935060208501356116d38161138e565b9250604085013567ffffffffffffffff808211156116f057600080fd5b818701915087601f83011261170457600080fd5b81358181111561171357600080fd5b88602082850101111561172557600080fd5b95989497505060200194505050565b6020808252602e908201527f54656c65706f727465725570677261646561626c653a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b60018060a01b03851681528360208201528260408201526080606082015260006104dd6080830184611643565b634e487b7160e01b600052603260045260246000fd5b602081526000610c196020830184611617565b634e487b7160e01b600052601160045260246000fd5b600060018201611800576118006117d8565b5060010190565b600181811c9082168061181b57607f821691505b60208210810361183b57634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561185357600080fd5b5051919050565b81810381811115610af457610af46117d8565b600081518084526020808501945080840160005b838110156118a65781516001600160a01b031687529582019590820190600101611881565b509495945050505050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c084015261191261010084018261186d565b905060a0840151601f198483030160e0850152610aef8282611617565b60006020828403121561194157600080fd5b815167ffffffffffffffff81111561195857600080fd5b8201601f8101841361196957600080fd5b805161197761154082611407565b81815285602083850101111561198c57600080fd5b61199d8260208301602086016115f3565b95945050505050565b601f8211156111f957600081815260208120601f850160051c810160208610156119cd5750805b601f850160051c820191505b818110156119ec578281556001016119d9565b505050505050565b815167ffffffffffffffff811115611a0e57611a0e6113c0565b611a2281611a1c8454611807565b846119a6565b602080601f831160018114611a575760008415611a3f5750858301515b600019600386901b1c1916600185901b1785556119ec565b600085815260208120601f198616915b82811015611a8657888601518255948401946001909101908401611a67565b5085821015611aa45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215611ac657600080fd5b8151610c198161138e565b80820180821115610af457610af46117d8565b600060208284031215611af657600080fd5b81518015158114610c1957600080fd5b60008251611b188184602087016115f3565b919091019291505056fea2646970667358221220257a55014d2e2efb8773812d91e07b56e09162796771c80a372b9e2533ff794f64736f6c63430008120033", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"teleporterManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minTeleporterVersion\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReceiveMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"messages\",\"type\":\"string[]\"}],\"name\":\"SendMessages\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"TeleporterAddressUnpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getCurrentMessages\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMinTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"isTeleporterAddressPaused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"pauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"string[]\",\"name\":\"messages\",\"type\":\"string[]\"}],\"name\":\"sendMessages\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterAddress\",\"type\":\"address\"}],\"name\":\"unpauseTeleporterAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"}],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b506040516121a63803806121a683398101604081905261002e9161062e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f811580156100775750825b90505f826001600160401b031660011480156100925750303b155b9050811580156100a0575080155b156100be5760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b031916600117855583156100ec57845460ff60401b1916680100000000000000001785555b6100f4610152565b6100ff888888610164565b831561014557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505061067e565b61015a610184565b6101626101d2565b565b61016c610184565b6101768382610200565b61017f82610226565b505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff1661016257604051631afcd79f60e31b815260040160405180910390fd5b6101da610184565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b610208610184565b610210610152565b61021861023a565b6102228282610242565b5050565b61022e610184565b610237816103d1565b50565b610162610184565b61024a610184565b6001600160a01b0382166102cb5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084015b60405180910390fd5b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610330573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103549190610667565b116103a95760405162461bcd60e51b815260206004820152603260248201525f80516020612186833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016102c2565b81546001600160a01b0319166001600160a01b0382161782556103cb8361040b565b50505050565b6103d9610184565b6001600160a01b03811661040257604051631e4fbdf760e01b81525f60048201526024016102c2565b610237816105a3565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104969190610667565b6002830154909150818411156104f55760405162461bcd60e51b815260206004820152603160248201525f8051602061218683398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016102c2565b80841161056a5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016102c2565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b80516001600160a01b0381168114610629575f80fd5b919050565b5f805f60608486031215610640575f80fd5b61064984610613565b925061065760208501610613565b9150604084015190509250925092565b5f60208284031215610677575f80fd5b5051919050565b611afb8061068b5f395ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063909a6ac01161006e578063909a6ac01461015b578063973142971461017d578063c1329fcb146101a0578063c868efaa146101c0578063d2cc7a70146101d3578063f2fde38b146101fa575f80fd5b80632b0d8f18146100b55780633902970c146100ca5780634511243e146100f35780635eb9951414610106578063715018a6146101195780638da5cb5b14610121575b5f80fd5b6100c86100c336600461137d565b61020d565b005b6100dd6100d8366004611404565b61030f565b6040516100ea9190611560565b60405180910390f35b6100c861010136600461137d565b6104fd565b6100c86101143660046115a3565b6105ec565b6100c8610600565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546040516001600160a01b0390911681526020016100ea565b61016f5f80516020611aa683398151915281565b6040519081526020016100ea565b61019061018b36600461137d565b610613565b60405190151581526020016100ea565b6101b36101ae3660046115a3565b610633565b6040516100ea919061165f565b6100c86101ce366004611671565b61070f565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d025461016f565b6100c861020836600461137d565b6108ed565b5f80516020611aa6833981519152610223610927565b6001600160a01b0382166102525760405162461bcd60e51b8152600401610249906116f3565b60405180910390fd5b61025c818361092f565b156102bf5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b6064820152608401610249565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b6060610319610953565b5f841561032d5761032a868661099d565b90505b866001600160a01b0316887f430d1906813fdb2129a19139f4112a1396804605501a798df3a4042590ba20d58884888860405161036d9493929190611741565b60405180910390a35f835167ffffffffffffffff81111561039057610390611398565b6040519080825280602002602001820160405280156103b9578160200160208202803683370190505b5090505f5b84518110156104c6575f61049d6040518060c001604052808d81526020018c6001600160a01b0316815260200160405180604001604052808d6001600160a01b031681526020018881525081526020018981526020015f67ffffffffffffffff81111561042d5761042d611398565b604051908082528060200260200182016040528015610456578160200160208202803683370190505b50815260200188858151811061046e5761046e61176d565b60200260200101516040516020016104869190611781565b6040516020818303038152906040528152506109a9565b9050808383815181106104b2576104b261176d565b6020908102919091010152506001016103be565b509150506104f360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b9695505050505050565b5f80516020611aa6833981519152610513610927565b6001600160a01b0382166105395760405162461bcd60e51b8152600401610249906116f3565b610543818361092f565b6105a15760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b6064820152608401610249565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b6105f4610927565b6105fd81610ac4565b50565b610608610c5c565b6106115f610cb7565b565b5f5f80516020611aa683398151915261062c818461092f565b9392505050565b5f81815260208181526040808320805482518185028101850190935280835260609493849084015b82821015610703578382905f5260205f2001805461067890611793565b80601f01602080910402602001604051908101604052809291908181526020018280546106a490611793565b80156106ef5780601f106106c6576101008083540402835291602001916106ef565b820191905f5260205f20905b8154815290600101906020018083116106d257829003601f168201915b50505050508152602001906001019061065b565b50929695505050505050565b610717610953565b5f5f80516020611aa683398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610782573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107a691906117cb565b101561080d5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b6064820152608401610249565b610817813361092f565b1561087d5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b6064820152608401610249565b6108bd858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610d2792505050565b506108e760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50505050565b6108f5610c5c565b6001600160a01b03811661091e57604051631e4fbdf760e01b81525f6004820152602401610249565b6105fd81610cb7565b610611610c5c565b6001600160a01b0381165f90815260018301602052604090205460ff165b92915050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0080546001190161099757604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f61062c833384610dad565b5f806109b3610f06565b60408401516020015190915015610a58576040830151516001600160a01b0316610a355760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b6064820152608401610249565b604083015160208101519051610a58916001600160a01b03909116908390610ff6565b604051630624488560e41b81526001600160a01b03821690636244885090610a84908690600401611825565b6020604051808303815f875af1158015610aa0573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062c91906117cb565b5f80516020611aa683398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610b18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3c91906117cb565b600283015490915081841115610bae5760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b6064820152608401610249565b808411610c235760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e006064820152608401610249565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b33610c8e7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146106115760405163118cdaa760e01b8152336004820152602401610249565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f81806020019051810190610d3c91906118a2565b5f8581526020818152604082208054600181018255908352912091925001610d648282611956565b50826001600160a01b0316847f1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa83604051610d9f9190611781565b60405180910390a350505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa158015610df3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e1791906117cb565b9050610e2e6001600160a01b03861685308661107d565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015610e72573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e9691906117cb565b9050818111610efc5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610249565b6104f38282611a2a565b5f80516020611aa683398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015610f60573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f849190611a3d565b9050610f90828261092f565b1561094d5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b6064820152608401610249565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa158015611043573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061106791906117cb565b90506108e784846110788585611a58565b6110e4565b6040516001600160a01b0384811660248301528381166044830152606482018390526108e79186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061116f565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261113584826111d5565b6108e7576040516001600160a01b0384811660248301525f604483015261116991869182169063095ea7b3906064016110b2565b6108e784825b5f6111836001600160a01b03841683611276565b905080515f141580156111a75750808060200190518101906111a59190611a6b565b155b156111d057604051635274afe760e01b81526001600160a01b0384166004820152602401610249565b505050565b5f805f846001600160a01b0316846040516111f09190611a8a565b5f604051808303815f865af19150503d805f8114611229576040519150601f19603f3d011682016040523d82523d5f602084013e61122e565b606091505b50915091508180156112585750805115806112585750808060200190518101906112589190611a6b565b801561126d57505f856001600160a01b03163b115b95945050505050565b606061062c83835f845f80856001600160a01b0316848660405161129a9190611a8a565b5f6040518083038185875af1925050503d805f81146112d4576040519150601f19603f3d011682016040523d82523d5f602084013e6112d9565b606091505b50915091506104f38683836060826112f9576112f482611340565b61062c565b815115801561131057506001600160a01b0384163b155b1561133957604051639996b31560e01b81526001600160a01b0385166004820152602401610249565b508061062c565b8051156113505780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b03811681146105fd575f80fd5b5f6020828403121561138d575f80fd5b813561062c81611369565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156113d5576113d5611398565b604052919050565b5f67ffffffffffffffff8211156113f6576113f6611398565b50601f01601f191660200190565b5f805f805f8060c08789031215611419575f80fd5b8635955061142a6020880135611369565b6020870135945061143e6040880135611369565b60408701359350606087013592506080870135915067ffffffffffffffff60a0880135111561146b575f80fd5b60a0870135870188601f820112611480575f80fd5b67ffffffffffffffff8135111561149957611499611398565b6114a96020823560051b016113ac565b81358082526020808301929160051b8401018b8111156114c7575f80fd5b602084015b8181101561154e5767ffffffffffffffff813511156114e9575f80fd5b803585018d603f8201126114fb575f80fd5b602081013561151161150c826113dd565b6113ac565b8181528f6040838501011115611525575f80fd5b816040840160208301375f602083830101528087525050506020840193506020810190506114cc565b50508093505050509295509295509295565b602080825282518282018190525f9190848201906040850190845b818110156115975783518352928401929184019160010161157b565b50909695505050505050565b5f602082840312156115b3575f80fd5b5035919050565b5f5b838110156115d45781810151838201526020016115bc565b50505f910152565b5f81518084526115f38160208601602086016115ba565b601f01601f19169290920160200192915050565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561165257601f198684030189526116408383516115dc565b98840198925090830190600101611624565b5090979650505050505050565b602081525f61062c6020830184611607565b5f805f8060608587031215611684575f80fd5b84359350602085013561169681611369565b9250604085013567ffffffffffffffff808211156116b2575f80fd5b818701915087601f8301126116c5575f80fd5b8135818111156116d3575f80fd5b8860208285010111156116e4575f80fd5b95989497505060200194505050565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b60018060a01b0385168152836020820152826040820152608060608201525f6104f36080830184611607565b634e487b7160e01b5f52603260045260245ffd5b602081525f61062c60208301846115dc565b600181811c908216806117a757607f821691505b6020821081036117c557634e487b7160e01b5f52602260045260245ffd5b50919050565b5f602082840312156117db575f80fd5b5051919050565b5f815180845260208085019450602084015f5b8381101561181a5781516001600160a01b0316875295820195908201906001016117f5565b509495945050505050565b60208152815160208201525f602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c08401526118856101008401826117e2565b905060a0840151601f198483030160e085015261126d82826115dc565b5f602082840312156118b2575f80fd5b815167ffffffffffffffff8111156118c8575f80fd5b8201601f810184136118d8575f80fd5b80516118e661150c826113dd565b8181528560208385010111156118fa575f80fd5b61126d8260208301602086016115ba565b601f8211156111d057805f5260205f20601f840160051c810160208510156119305750805b601f840160051c820191505b8181101561194f575f815560010161193c565b5050505050565b815167ffffffffffffffff81111561197057611970611398565b6119848161197e8454611793565b8461190b565b602080601f8311600181146119b7575f84156119a05750858301515b5f19600386901b1c1916600185901b178555611a0e565b5f85815260208120601f198616915b828110156119e5578886015182559484019460019091019084016119c6565b5085821015611a0257878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561094d5761094d611a16565b5f60208284031215611a4d575f80fd5b815161062c81611369565b8082018082111561094d5761094d611a16565b5f60208284031215611a7b575f80fd5b8151801515811461062c575f80fd5b5f8251611a9b8184602087016115ba565b919091019291505056fede77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a2646970667358221220a6d5ec9aec6eecdda4f37aee707471da357a4413a9b2d41109c35e7c076fc2b564736f6c6343000819003354656c65706f7274657252656769737472794170703a20696e76616c69642054", } // BatchCrossChainMessengerABI is the input ABI used to generate the binding from. @@ -44,7 +44,7 @@ var BatchCrossChainMessengerABI = BatchCrossChainMessengerMetaData.ABI var BatchCrossChainMessengerBin = BatchCrossChainMessengerMetaData.Bin // DeployBatchCrossChainMessenger deploys a new Ethereum contract, binding an instance of BatchCrossChainMessenger to it. -func DeployBatchCrossChainMessenger(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterRegistryAddress common.Address, teleporterManager common.Address) (common.Address, *types.Transaction, *BatchCrossChainMessenger, error) { +func DeployBatchCrossChainMessenger(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterRegistryAddress common.Address, teleporterManager common.Address, minTeleporterVersion *big.Int) (common.Address, *types.Transaction, *BatchCrossChainMessenger, error) { parsed, err := BatchCrossChainMessengerMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -53,7 +53,7 @@ func DeployBatchCrossChainMessenger(auth *bind.TransactOpts, backend bind.Contra return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BatchCrossChainMessengerBin), backend, teleporterRegistryAddress, teleporterManager) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BatchCrossChainMessengerBin), backend, teleporterRegistryAddress, teleporterManager, minTeleporterVersion) if err != nil { return common.Address{}, nil, nil, err } @@ -202,6 +202,37 @@ func (_BatchCrossChainMessenger *BatchCrossChainMessengerTransactorRaw) Transact return _BatchCrossChainMessenger.Contract.contract.Transact(opts, method, params...) } +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_BatchCrossChainMessenger *BatchCrossChainMessengerCaller) TELEPORTERREGISTRYAPPSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _BatchCrossChainMessenger.contract.Call(opts, &out, "TELEPORTER_REGISTRY_APP_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_BatchCrossChainMessenger *BatchCrossChainMessengerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _BatchCrossChainMessenger.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_BatchCrossChainMessenger.CallOpts) +} + +// TELEPORTERREGISTRYAPPSTORAGELOCATION is a free data retrieval call binding the contract method 0x909a6ac0. +// +// Solidity: function TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() view returns(bytes32) +func (_BatchCrossChainMessenger *BatchCrossChainMessengerCallerSession) TELEPORTERREGISTRYAPPSTORAGELOCATION() ([32]byte, error) { + return _BatchCrossChainMessenger.Contract.TELEPORTERREGISTRYAPPSTORAGELOCATION(&_BatchCrossChainMessenger.CallOpts) +} + // GetCurrentMessages is a free data retrieval call binding the contract method 0xc1329fcb. // // Solidity: function getCurrentMessages(bytes32 sourceBlockchainID) view returns(string[]) @@ -326,37 +357,6 @@ func (_BatchCrossChainMessenger *BatchCrossChainMessengerCallerSession) Owner() return _BatchCrossChainMessenger.Contract.Owner(&_BatchCrossChainMessenger.CallOpts) } -// TeleporterRegistry is a free data retrieval call binding the contract method 0x1a7f5bec. -// -// Solidity: function teleporterRegistry() view returns(address) -func (_BatchCrossChainMessenger *BatchCrossChainMessengerCaller) TeleporterRegistry(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _BatchCrossChainMessenger.contract.Call(opts, &out, "teleporterRegistry") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// TeleporterRegistry is a free data retrieval call binding the contract method 0x1a7f5bec. -// -// Solidity: function teleporterRegistry() view returns(address) -func (_BatchCrossChainMessenger *BatchCrossChainMessengerSession) TeleporterRegistry() (common.Address, error) { - return _BatchCrossChainMessenger.Contract.TeleporterRegistry(&_BatchCrossChainMessenger.CallOpts) -} - -// TeleporterRegistry is a free data retrieval call binding the contract method 0x1a7f5bec. -// -// Solidity: function teleporterRegistry() view returns(address) -func (_BatchCrossChainMessenger *BatchCrossChainMessengerCallerSession) TeleporterRegistry() (common.Address, error) { - return _BatchCrossChainMessenger.Contract.TeleporterRegistry(&_BatchCrossChainMessenger.CallOpts) -} - // PauseTeleporterAddress is a paid mutator transaction binding the contract method 0x2b0d8f18. // // Solidity: function pauseTeleporterAddress(address teleporterAddress) returns() @@ -504,6 +504,140 @@ func (_BatchCrossChainMessenger *BatchCrossChainMessengerTransactorSession) Upda return _BatchCrossChainMessenger.Contract.UpdateMinTeleporterVersion(&_BatchCrossChainMessenger.TransactOpts, version) } +// BatchCrossChainMessengerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the BatchCrossChainMessenger contract. +type BatchCrossChainMessengerInitializedIterator struct { + Event *BatchCrossChainMessengerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *BatchCrossChainMessengerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(BatchCrossChainMessengerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(BatchCrossChainMessengerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *BatchCrossChainMessengerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *BatchCrossChainMessengerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// BatchCrossChainMessengerInitialized represents a Initialized event raised by the BatchCrossChainMessenger contract. +type BatchCrossChainMessengerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_BatchCrossChainMessenger *BatchCrossChainMessengerFilterer) FilterInitialized(opts *bind.FilterOpts) (*BatchCrossChainMessengerInitializedIterator, error) { + + logs, sub, err := _BatchCrossChainMessenger.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &BatchCrossChainMessengerInitializedIterator{contract: _BatchCrossChainMessenger.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_BatchCrossChainMessenger *BatchCrossChainMessengerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *BatchCrossChainMessengerInitialized) (event.Subscription, error) { + + logs, sub, err := _BatchCrossChainMessenger.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(BatchCrossChainMessengerInitialized) + if err := _BatchCrossChainMessenger.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_BatchCrossChainMessenger *BatchCrossChainMessengerFilterer) ParseInitialized(log types.Log) (*BatchCrossChainMessengerInitialized, error) { + event := new(BatchCrossChainMessengerInitialized) + if err := _BatchCrossChainMessenger.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // BatchCrossChainMessengerMinTeleporterVersionUpdatedIterator is returned from FilterMinTeleporterVersionUpdated and is used to iterate over the raw logs and unpacked data for MinTeleporterVersionUpdated events raised by the BatchCrossChainMessenger contract. type BatchCrossChainMessengerMinTeleporterVersionUpdatedIterator struct { Event *BatchCrossChainMessengerMinTeleporterVersionUpdated // Event containing the contract specifics and raw log diff --git a/abi-bindings/go/validator-manager/ACP99Manager/ACP99Manager.go b/abi-bindings/go/validator-manager/ACP99Manager/ACP99Manager.go new file mode 100644 index 000000000..3cb5307ba --- /dev/null +++ b/abi-bindings/go/validator-manager/ACP99Manager/ACP99Manager.go @@ -0,0 +1,1433 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package acp99manager + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ConversionData is an auto generated low-level Go binding around an user-defined struct. +type ConversionData struct { + SubnetID [32]byte + ValidatorManagerBlockchainID [32]byte + ValidatorManagerAddress common.Address + InitialValidators []InitialValidator +} + +// InitialValidator is an auto generated low-level Go binding around an user-defined struct. +type InitialValidator struct { + NodeID []byte + BlsPublicKey []byte + Weight uint64 +} + +// Validator is an auto generated low-level Go binding around an user-defined struct. +type Validator struct { + Status uint8 + NodeID []byte + StartingWeight uint64 + SentNonce uint64 + ReceivedNonce uint64 + Weight uint64 + StartTime uint64 + EndTime uint64 +} + +// ACP99ManagerMetaData contains all meta data concerning the ACP99Manager contract. +var ACP99ManagerMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"CompletedValidatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"CompletedValidatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"CompletedValidatorWeightUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"nodeID\",\"type\":\"bytes20\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"registrationMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"InitiatedValidatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"validatorWeightMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"endTime\",\"type\":\"uint64\"}],\"name\":\"InitiatedValidatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"weightUpdateMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"InitiatedValidatorWeightUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"nodeID\",\"type\":\"bytes20\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"RegisteredInitialValidator\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRemoval\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorWeightUpdate\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"getValidator\",\"outputs\":[{\"components\":[{\"internalType\":\"enumValidatorStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"startingWeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sentNonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"receivedNonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"startTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"endTime\",\"type\":\"uint64\"}],\"internalType\":\"structValidator\",\"name\":\"validator\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"validatorManagerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structInitialValidator[]\",\"name\":\"initialValidators\",\"type\":\"tuple[]\"}],\"internalType\":\"structConversionData\",\"name\":\"conversionData\",\"type\":\"tuple\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initializeValidatorSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1TotalWeight\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"subnetID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// ACP99ManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ACP99ManagerMetaData.ABI instead. +var ACP99ManagerABI = ACP99ManagerMetaData.ABI + +// ACP99Manager is an auto generated Go binding around an Ethereum contract. +type ACP99Manager struct { + ACP99ManagerCaller // Read-only binding to the contract + ACP99ManagerTransactor // Write-only binding to the contract + ACP99ManagerFilterer // Log filterer for contract events +} + +// ACP99ManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ACP99ManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ACP99ManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ACP99ManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ACP99ManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ACP99ManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ACP99ManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ACP99ManagerSession struct { + Contract *ACP99Manager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ACP99ManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ACP99ManagerCallerSession struct { + Contract *ACP99ManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ACP99ManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ACP99ManagerTransactorSession struct { + Contract *ACP99ManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ACP99ManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ACP99ManagerRaw struct { + Contract *ACP99Manager // Generic contract binding to access the raw methods on +} + +// ACP99ManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ACP99ManagerCallerRaw struct { + Contract *ACP99ManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ACP99ManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ACP99ManagerTransactorRaw struct { + Contract *ACP99ManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewACP99Manager creates a new instance of ACP99Manager, bound to a specific deployed contract. +func NewACP99Manager(address common.Address, backend bind.ContractBackend) (*ACP99Manager, error) { + contract, err := bindACP99Manager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ACP99Manager{ACP99ManagerCaller: ACP99ManagerCaller{contract: contract}, ACP99ManagerTransactor: ACP99ManagerTransactor{contract: contract}, ACP99ManagerFilterer: ACP99ManagerFilterer{contract: contract}}, nil +} + +// NewACP99ManagerCaller creates a new read-only instance of ACP99Manager, bound to a specific deployed contract. +func NewACP99ManagerCaller(address common.Address, caller bind.ContractCaller) (*ACP99ManagerCaller, error) { + contract, err := bindACP99Manager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ACP99ManagerCaller{contract: contract}, nil +} + +// NewACP99ManagerTransactor creates a new write-only instance of ACP99Manager, bound to a specific deployed contract. +func NewACP99ManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ACP99ManagerTransactor, error) { + contract, err := bindACP99Manager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ACP99ManagerTransactor{contract: contract}, nil +} + +// NewACP99ManagerFilterer creates a new log filterer instance of ACP99Manager, bound to a specific deployed contract. +func NewACP99ManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ACP99ManagerFilterer, error) { + contract, err := bindACP99Manager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ACP99ManagerFilterer{contract: contract}, nil +} + +// bindACP99Manager binds a generic wrapper to an already deployed contract. +func bindACP99Manager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ACP99ManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ACP99Manager *ACP99ManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ACP99Manager.Contract.ACP99ManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ACP99Manager *ACP99ManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ACP99Manager.Contract.ACP99ManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ACP99Manager *ACP99ManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ACP99Manager.Contract.ACP99ManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ACP99Manager *ACP99ManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ACP99Manager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ACP99Manager *ACP99ManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ACP99Manager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ACP99Manager *ACP99ManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ACP99Manager.Contract.contract.Transact(opts, method, params...) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes,uint64,uint64,uint64,uint64,uint64,uint64) validator) +func (_ACP99Manager *ACP99ManagerCaller) GetValidator(opts *bind.CallOpts, validationID [32]byte) (Validator, error) { + var out []interface{} + err := _ACP99Manager.contract.Call(opts, &out, "getValidator", validationID) + + if err != nil { + return *new(Validator), err + } + + out0 := *abi.ConvertType(out[0], new(Validator)).(*Validator) + + return out0, err + +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes,uint64,uint64,uint64,uint64,uint64,uint64) validator) +func (_ACP99Manager *ACP99ManagerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _ACP99Manager.Contract.GetValidator(&_ACP99Manager.CallOpts, validationID) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes,uint64,uint64,uint64,uint64,uint64,uint64) validator) +func (_ACP99Manager *ACP99ManagerCallerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _ACP99Manager.Contract.GetValidator(&_ACP99Manager.CallOpts, validationID) +} + +// L1TotalWeight is a free data retrieval call binding the contract method 0xbb0b1938. +// +// Solidity: function l1TotalWeight() view returns(uint64 weight) +func (_ACP99Manager *ACP99ManagerCaller) L1TotalWeight(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ACP99Manager.contract.Call(opts, &out, "l1TotalWeight") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// L1TotalWeight is a free data retrieval call binding the contract method 0xbb0b1938. +// +// Solidity: function l1TotalWeight() view returns(uint64 weight) +func (_ACP99Manager *ACP99ManagerSession) L1TotalWeight() (uint64, error) { + return _ACP99Manager.Contract.L1TotalWeight(&_ACP99Manager.CallOpts) +} + +// L1TotalWeight is a free data retrieval call binding the contract method 0xbb0b1938. +// +// Solidity: function l1TotalWeight() view returns(uint64 weight) +func (_ACP99Manager *ACP99ManagerCallerSession) L1TotalWeight() (uint64, error) { + return _ACP99Manager.Contract.L1TotalWeight(&_ACP99Manager.CallOpts) +} + +// SubnetID is a free data retrieval call binding the contract method 0x5dc1f535. +// +// Solidity: function subnetID() view returns(bytes32 id) +func (_ACP99Manager *ACP99ManagerCaller) SubnetID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ACP99Manager.contract.Call(opts, &out, "subnetID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// SubnetID is a free data retrieval call binding the contract method 0x5dc1f535. +// +// Solidity: function subnetID() view returns(bytes32 id) +func (_ACP99Manager *ACP99ManagerSession) SubnetID() ([32]byte, error) { + return _ACP99Manager.Contract.SubnetID(&_ACP99Manager.CallOpts) +} + +// SubnetID is a free data retrieval call binding the contract method 0x5dc1f535. +// +// Solidity: function subnetID() view returns(bytes32 id) +func (_ACP99Manager *ACP99ManagerCallerSession) SubnetID() ([32]byte, error) { + return _ACP99Manager.Contract.SubnetID(&_ACP99Manager.CallOpts) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32 validationID) +func (_ACP99Manager *ACP99ManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32 validationID) +func (_ACP99Manager *ACP99ManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.CompleteValidatorRegistration(&_ACP99Manager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32 validationID) +func (_ACP99Manager *ACP99ManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.CompleteValidatorRegistration(&_ACP99Manager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32 validationID) +func (_ACP99Manager *ACP99ManagerTransactor) CompleteValidatorRemoval(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.contract.Transact(opts, "completeValidatorRemoval", messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32 validationID) +func (_ACP99Manager *ACP99ManagerSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.CompleteValidatorRemoval(&_ACP99Manager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32 validationID) +func (_ACP99Manager *ACP99ManagerTransactorSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.CompleteValidatorRemoval(&_ACP99Manager.TransactOpts, messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32 validationID, uint64 nonce) +func (_ACP99Manager *ACP99ManagerTransactor) CompleteValidatorWeightUpdate(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.contract.Transact(opts, "completeValidatorWeightUpdate", messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32 validationID, uint64 nonce) +func (_ACP99Manager *ACP99ManagerSession) CompleteValidatorWeightUpdate(messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.CompleteValidatorWeightUpdate(&_ACP99Manager.TransactOpts, messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32 validationID, uint64 nonce) +func (_ACP99Manager *ACP99ManagerTransactorSession) CompleteValidatorWeightUpdate(messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.CompleteValidatorWeightUpdate(&_ACP99Manager.TransactOpts, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x20d91b7a. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData, uint32 messageIndex) returns() +func (_ACP99Manager *ACP99ManagerTransactor) InitializeValidatorSet(opts *bind.TransactOpts, conversionData ConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.contract.Transact(opts, "initializeValidatorSet", conversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x20d91b7a. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData, uint32 messageIndex) returns() +func (_ACP99Manager *ACP99ManagerSession) InitializeValidatorSet(conversionData ConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.InitializeValidatorSet(&_ACP99Manager.TransactOpts, conversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x20d91b7a. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData, uint32 messageIndex) returns() +func (_ACP99Manager *ACP99ManagerTransactorSession) InitializeValidatorSet(conversionData ConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ACP99Manager.Contract.InitializeValidatorSet(&_ACP99Manager.TransactOpts, conversionData, messageIndex) +} + +// ACP99ManagerCompletedValidatorRegistrationIterator is returned from FilterCompletedValidatorRegistration and is used to iterate over the raw logs and unpacked data for CompletedValidatorRegistration events raised by the ACP99Manager contract. +type ACP99ManagerCompletedValidatorRegistrationIterator struct { + Event *ACP99ManagerCompletedValidatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ACP99ManagerCompletedValidatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerCompletedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerCompletedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ACP99ManagerCompletedValidatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ACP99ManagerCompletedValidatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ACP99ManagerCompletedValidatorRegistration represents a CompletedValidatorRegistration event raised by the ACP99Manager contract. +type ACP99ManagerCompletedValidatorRegistration struct { + ValidationID [32]byte + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedValidatorRegistration is a free log retrieval operation binding the contract event 0x967ae87813a3b5f201dd9bcba778d457176eafe6f41facee1c718091d3952d06. +// +// Solidity: event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) FilterCompletedValidatorRegistration(opts *bind.FilterOpts, validationID [][32]byte) (*ACP99ManagerCompletedValidatorRegistrationIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.FilterLogs(opts, "CompletedValidatorRegistration", validationIDRule) + if err != nil { + return nil, err + } + return &ACP99ManagerCompletedValidatorRegistrationIterator{contract: _ACP99Manager.contract, event: "CompletedValidatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchCompletedValidatorRegistration is a free log subscription operation binding the contract event 0x967ae87813a3b5f201dd9bcba778d457176eafe6f41facee1c718091d3952d06. +// +// Solidity: event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) WatchCompletedValidatorRegistration(opts *bind.WatchOpts, sink chan<- *ACP99ManagerCompletedValidatorRegistration, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.WatchLogs(opts, "CompletedValidatorRegistration", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ACP99ManagerCompletedValidatorRegistration) + if err := _ACP99Manager.contract.UnpackLog(event, "CompletedValidatorRegistration", 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 +} + +// ParseCompletedValidatorRegistration is a log parse operation binding the contract event 0x967ae87813a3b5f201dd9bcba778d457176eafe6f41facee1c718091d3952d06. +// +// Solidity: event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) ParseCompletedValidatorRegistration(log types.Log) (*ACP99ManagerCompletedValidatorRegistration, error) { + event := new(ACP99ManagerCompletedValidatorRegistration) + if err := _ACP99Manager.contract.UnpackLog(event, "CompletedValidatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ACP99ManagerCompletedValidatorRemovalIterator is returned from FilterCompletedValidatorRemoval and is used to iterate over the raw logs and unpacked data for CompletedValidatorRemoval events raised by the ACP99Manager contract. +type ACP99ManagerCompletedValidatorRemovalIterator struct { + Event *ACP99ManagerCompletedValidatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ACP99ManagerCompletedValidatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerCompletedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerCompletedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ACP99ManagerCompletedValidatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ACP99ManagerCompletedValidatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ACP99ManagerCompletedValidatorRemoval represents a CompletedValidatorRemoval event raised by the ACP99Manager contract. +type ACP99ManagerCompletedValidatorRemoval struct { + ValidationID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedValidatorRemoval is a free log retrieval operation binding the contract event 0xafaccef7080649a725bc30a35359a257a4a27225be352875c80bdf6b5f04080c. +// +// Solidity: event CompletedValidatorRemoval(bytes32 indexed validationID) +func (_ACP99Manager *ACP99ManagerFilterer) FilterCompletedValidatorRemoval(opts *bind.FilterOpts, validationID [][32]byte) (*ACP99ManagerCompletedValidatorRemovalIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.FilterLogs(opts, "CompletedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return &ACP99ManagerCompletedValidatorRemovalIterator{contract: _ACP99Manager.contract, event: "CompletedValidatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchCompletedValidatorRemoval is a free log subscription operation binding the contract event 0xafaccef7080649a725bc30a35359a257a4a27225be352875c80bdf6b5f04080c. +// +// Solidity: event CompletedValidatorRemoval(bytes32 indexed validationID) +func (_ACP99Manager *ACP99ManagerFilterer) WatchCompletedValidatorRemoval(opts *bind.WatchOpts, sink chan<- *ACP99ManagerCompletedValidatorRemoval, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.WatchLogs(opts, "CompletedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ACP99ManagerCompletedValidatorRemoval) + if err := _ACP99Manager.contract.UnpackLog(event, "CompletedValidatorRemoval", 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 +} + +// ParseCompletedValidatorRemoval is a log parse operation binding the contract event 0xafaccef7080649a725bc30a35359a257a4a27225be352875c80bdf6b5f04080c. +// +// Solidity: event CompletedValidatorRemoval(bytes32 indexed validationID) +func (_ACP99Manager *ACP99ManagerFilterer) ParseCompletedValidatorRemoval(log types.Log) (*ACP99ManagerCompletedValidatorRemoval, error) { + event := new(ACP99ManagerCompletedValidatorRemoval) + if err := _ACP99Manager.contract.UnpackLog(event, "CompletedValidatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ACP99ManagerCompletedValidatorWeightUpdateIterator is returned from FilterCompletedValidatorWeightUpdate and is used to iterate over the raw logs and unpacked data for CompletedValidatorWeightUpdate events raised by the ACP99Manager contract. +type ACP99ManagerCompletedValidatorWeightUpdateIterator struct { + Event *ACP99ManagerCompletedValidatorWeightUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ACP99ManagerCompletedValidatorWeightUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerCompletedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerCompletedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ACP99ManagerCompletedValidatorWeightUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ACP99ManagerCompletedValidatorWeightUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ACP99ManagerCompletedValidatorWeightUpdate represents a CompletedValidatorWeightUpdate event raised by the ACP99Manager contract. +type ACP99ManagerCompletedValidatorWeightUpdate struct { + ValidationID [32]byte + Nonce uint64 + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedValidatorWeightUpdate is a free log retrieval operation binding the contract event 0xc917996591802ecedcfced71321d4bb5320f7dfbacf5477dffe1dbf8b8839ff9. +// +// Solidity: event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) FilterCompletedValidatorWeightUpdate(opts *bind.FilterOpts, validationID [][32]byte) (*ACP99ManagerCompletedValidatorWeightUpdateIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.FilterLogs(opts, "CompletedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return &ACP99ManagerCompletedValidatorWeightUpdateIterator{contract: _ACP99Manager.contract, event: "CompletedValidatorWeightUpdate", logs: logs, sub: sub}, nil +} + +// WatchCompletedValidatorWeightUpdate is a free log subscription operation binding the contract event 0xc917996591802ecedcfced71321d4bb5320f7dfbacf5477dffe1dbf8b8839ff9. +// +// Solidity: event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) WatchCompletedValidatorWeightUpdate(opts *bind.WatchOpts, sink chan<- *ACP99ManagerCompletedValidatorWeightUpdate, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.WatchLogs(opts, "CompletedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ACP99ManagerCompletedValidatorWeightUpdate) + if err := _ACP99Manager.contract.UnpackLog(event, "CompletedValidatorWeightUpdate", 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 +} + +// ParseCompletedValidatorWeightUpdate is a log parse operation binding the contract event 0xc917996591802ecedcfced71321d4bb5320f7dfbacf5477dffe1dbf8b8839ff9. +// +// Solidity: event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) ParseCompletedValidatorWeightUpdate(log types.Log) (*ACP99ManagerCompletedValidatorWeightUpdate, error) { + event := new(ACP99ManagerCompletedValidatorWeightUpdate) + if err := _ACP99Manager.contract.UnpackLog(event, "CompletedValidatorWeightUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ACP99ManagerInitiatedValidatorRegistrationIterator is returned from FilterInitiatedValidatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedValidatorRegistration events raised by the ACP99Manager contract. +type ACP99ManagerInitiatedValidatorRegistrationIterator struct { + Event *ACP99ManagerInitiatedValidatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ACP99ManagerInitiatedValidatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerInitiatedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerInitiatedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ACP99ManagerInitiatedValidatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ACP99ManagerInitiatedValidatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ACP99ManagerInitiatedValidatorRegistration represents a InitiatedValidatorRegistration event raised by the ACP99Manager contract. +type ACP99ManagerInitiatedValidatorRegistration struct { + ValidationID [32]byte + NodeID [20]byte + RegistrationMessageID [32]byte + RegistrationExpiry uint64 + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedValidatorRegistration is a free log retrieval operation binding the contract event 0x5881be437bdcb008bfa5f20e32d3e335ccf8ab90ef2818852a251625260af35d. +// +// Solidity: event InitiatedValidatorRegistration(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 registrationMessageID, uint64 registrationExpiry, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) FilterInitiatedValidatorRegistration(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][20]byte) (*ACP99ManagerInitiatedValidatorRegistrationIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _ACP99Manager.contract.FilterLogs(opts, "InitiatedValidatorRegistration", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return &ACP99ManagerInitiatedValidatorRegistrationIterator{contract: _ACP99Manager.contract, event: "InitiatedValidatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedValidatorRegistration is a free log subscription operation binding the contract event 0x5881be437bdcb008bfa5f20e32d3e335ccf8ab90ef2818852a251625260af35d. +// +// Solidity: event InitiatedValidatorRegistration(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 registrationMessageID, uint64 registrationExpiry, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) WatchInitiatedValidatorRegistration(opts *bind.WatchOpts, sink chan<- *ACP99ManagerInitiatedValidatorRegistration, validationID [][32]byte, nodeID [][20]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _ACP99Manager.contract.WatchLogs(opts, "InitiatedValidatorRegistration", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ACP99ManagerInitiatedValidatorRegistration) + if err := _ACP99Manager.contract.UnpackLog(event, "InitiatedValidatorRegistration", 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 +} + +// ParseInitiatedValidatorRegistration is a log parse operation binding the contract event 0x5881be437bdcb008bfa5f20e32d3e335ccf8ab90ef2818852a251625260af35d. +// +// Solidity: event InitiatedValidatorRegistration(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 registrationMessageID, uint64 registrationExpiry, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) ParseInitiatedValidatorRegistration(log types.Log) (*ACP99ManagerInitiatedValidatorRegistration, error) { + event := new(ACP99ManagerInitiatedValidatorRegistration) + if err := _ACP99Manager.contract.UnpackLog(event, "InitiatedValidatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ACP99ManagerInitiatedValidatorRemovalIterator is returned from FilterInitiatedValidatorRemoval and is used to iterate over the raw logs and unpacked data for InitiatedValidatorRemoval events raised by the ACP99Manager contract. +type ACP99ManagerInitiatedValidatorRemovalIterator struct { + Event *ACP99ManagerInitiatedValidatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ACP99ManagerInitiatedValidatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerInitiatedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerInitiatedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ACP99ManagerInitiatedValidatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ACP99ManagerInitiatedValidatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ACP99ManagerInitiatedValidatorRemoval represents a InitiatedValidatorRemoval event raised by the ACP99Manager contract. +type ACP99ManagerInitiatedValidatorRemoval struct { + ValidationID [32]byte + ValidatorWeightMessageID [32]byte + Weight uint64 + EndTime uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedValidatorRemoval is a free log retrieval operation binding the contract event 0xbae388a94e7f18411fe57098f12f418b8e1a8273e0532a90188a3a059b897273. +// +// Solidity: event InitiatedValidatorRemoval(bytes32 indexed validationID, bytes32 validatorWeightMessageID, uint64 weight, uint64 endTime) +func (_ACP99Manager *ACP99ManagerFilterer) FilterInitiatedValidatorRemoval(opts *bind.FilterOpts, validationID [][32]byte) (*ACP99ManagerInitiatedValidatorRemovalIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.FilterLogs(opts, "InitiatedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return &ACP99ManagerInitiatedValidatorRemovalIterator{contract: _ACP99Manager.contract, event: "InitiatedValidatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchInitiatedValidatorRemoval is a free log subscription operation binding the contract event 0xbae388a94e7f18411fe57098f12f418b8e1a8273e0532a90188a3a059b897273. +// +// Solidity: event InitiatedValidatorRemoval(bytes32 indexed validationID, bytes32 validatorWeightMessageID, uint64 weight, uint64 endTime) +func (_ACP99Manager *ACP99ManagerFilterer) WatchInitiatedValidatorRemoval(opts *bind.WatchOpts, sink chan<- *ACP99ManagerInitiatedValidatorRemoval, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.WatchLogs(opts, "InitiatedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ACP99ManagerInitiatedValidatorRemoval) + if err := _ACP99Manager.contract.UnpackLog(event, "InitiatedValidatorRemoval", 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 +} + +// ParseInitiatedValidatorRemoval is a log parse operation binding the contract event 0xbae388a94e7f18411fe57098f12f418b8e1a8273e0532a90188a3a059b897273. +// +// Solidity: event InitiatedValidatorRemoval(bytes32 indexed validationID, bytes32 validatorWeightMessageID, uint64 weight, uint64 endTime) +func (_ACP99Manager *ACP99ManagerFilterer) ParseInitiatedValidatorRemoval(log types.Log) (*ACP99ManagerInitiatedValidatorRemoval, error) { + event := new(ACP99ManagerInitiatedValidatorRemoval) + if err := _ACP99Manager.contract.UnpackLog(event, "InitiatedValidatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ACP99ManagerInitiatedValidatorWeightUpdateIterator is returned from FilterInitiatedValidatorWeightUpdate and is used to iterate over the raw logs and unpacked data for InitiatedValidatorWeightUpdate events raised by the ACP99Manager contract. +type ACP99ManagerInitiatedValidatorWeightUpdateIterator struct { + Event *ACP99ManagerInitiatedValidatorWeightUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ACP99ManagerInitiatedValidatorWeightUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerInitiatedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerInitiatedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ACP99ManagerInitiatedValidatorWeightUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ACP99ManagerInitiatedValidatorWeightUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ACP99ManagerInitiatedValidatorWeightUpdate represents a InitiatedValidatorWeightUpdate event raised by the ACP99Manager contract. +type ACP99ManagerInitiatedValidatorWeightUpdate struct { + ValidationID [32]byte + Nonce uint64 + WeightUpdateMessageID [32]byte + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedValidatorWeightUpdate is a free log retrieval operation binding the contract event 0x6e350dd49b060d87f297206fd309234ed43156d890ced0f139ecf704310481d3. +// +// Solidity: event InitiatedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) FilterInitiatedValidatorWeightUpdate(opts *bind.FilterOpts, validationID [][32]byte) (*ACP99ManagerInitiatedValidatorWeightUpdateIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.FilterLogs(opts, "InitiatedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return &ACP99ManagerInitiatedValidatorWeightUpdateIterator{contract: _ACP99Manager.contract, event: "InitiatedValidatorWeightUpdate", logs: logs, sub: sub}, nil +} + +// WatchInitiatedValidatorWeightUpdate is a free log subscription operation binding the contract event 0x6e350dd49b060d87f297206fd309234ed43156d890ced0f139ecf704310481d3. +// +// Solidity: event InitiatedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) WatchInitiatedValidatorWeightUpdate(opts *bind.WatchOpts, sink chan<- *ACP99ManagerInitiatedValidatorWeightUpdate, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ACP99Manager.contract.WatchLogs(opts, "InitiatedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ACP99ManagerInitiatedValidatorWeightUpdate) + if err := _ACP99Manager.contract.UnpackLog(event, "InitiatedValidatorWeightUpdate", 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 +} + +// ParseInitiatedValidatorWeightUpdate is a log parse operation binding the contract event 0x6e350dd49b060d87f297206fd309234ed43156d890ced0f139ecf704310481d3. +// +// Solidity: event InitiatedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) ParseInitiatedValidatorWeightUpdate(log types.Log) (*ACP99ManagerInitiatedValidatorWeightUpdate, error) { + event := new(ACP99ManagerInitiatedValidatorWeightUpdate) + if err := _ACP99Manager.contract.UnpackLog(event, "InitiatedValidatorWeightUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ACP99ManagerRegisteredInitialValidatorIterator is returned from FilterRegisteredInitialValidator and is used to iterate over the raw logs and unpacked data for RegisteredInitialValidator events raised by the ACP99Manager contract. +type ACP99ManagerRegisteredInitialValidatorIterator struct { + Event *ACP99ManagerRegisteredInitialValidator // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ACP99ManagerRegisteredInitialValidatorIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerRegisteredInitialValidator) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ACP99ManagerRegisteredInitialValidator) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ACP99ManagerRegisteredInitialValidatorIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ACP99ManagerRegisteredInitialValidatorIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ACP99ManagerRegisteredInitialValidator represents a RegisteredInitialValidator event raised by the ACP99Manager contract. +type ACP99ManagerRegisteredInitialValidator struct { + ValidationID [32]byte + NodeID [20]byte + SubnetID [32]byte + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRegisteredInitialValidator is a free log retrieval operation binding the contract event 0x070e0f6540afd612d613b71036a6d45f8c5fa97770a7e2d55663d75474ce0c0d. +// +// Solidity: event RegisteredInitialValidator(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 indexed subnetID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) FilterRegisteredInitialValidator(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][20]byte, subnetID [][32]byte) (*ACP99ManagerRegisteredInitialValidatorIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var subnetIDRule []interface{} + for _, subnetIDItem := range subnetID { + subnetIDRule = append(subnetIDRule, subnetIDItem) + } + + logs, sub, err := _ACP99Manager.contract.FilterLogs(opts, "RegisteredInitialValidator", validationIDRule, nodeIDRule, subnetIDRule) + if err != nil { + return nil, err + } + return &ACP99ManagerRegisteredInitialValidatorIterator{contract: _ACP99Manager.contract, event: "RegisteredInitialValidator", logs: logs, sub: sub}, nil +} + +// WatchRegisteredInitialValidator is a free log subscription operation binding the contract event 0x070e0f6540afd612d613b71036a6d45f8c5fa97770a7e2d55663d75474ce0c0d. +// +// Solidity: event RegisteredInitialValidator(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 indexed subnetID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) WatchRegisteredInitialValidator(opts *bind.WatchOpts, sink chan<- *ACP99ManagerRegisteredInitialValidator, validationID [][32]byte, nodeID [][20]byte, subnetID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var subnetIDRule []interface{} + for _, subnetIDItem := range subnetID { + subnetIDRule = append(subnetIDRule, subnetIDItem) + } + + logs, sub, err := _ACP99Manager.contract.WatchLogs(opts, "RegisteredInitialValidator", validationIDRule, nodeIDRule, subnetIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ACP99ManagerRegisteredInitialValidator) + if err := _ACP99Manager.contract.UnpackLog(event, "RegisteredInitialValidator", 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 +} + +// ParseRegisteredInitialValidator is a log parse operation binding the contract event 0x070e0f6540afd612d613b71036a6d45f8c5fa97770a7e2d55663d75474ce0c0d. +// +// Solidity: event RegisteredInitialValidator(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 indexed subnetID, uint64 weight) +func (_ACP99Manager *ACP99ManagerFilterer) ParseRegisteredInitialValidator(log types.Log) (*ACP99ManagerRegisteredInitialValidator, error) { + event := new(ACP99ManagerRegisteredInitialValidator) + if err := _ACP99Manager.contract.UnpackLog(event, "RegisteredInitialValidator", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/validator-manager/ERC20TokenStakingManager/ERC20TokenStakingManager.go b/abi-bindings/go/validator-manager/ERC20TokenStakingManager/ERC20TokenStakingManager.go new file mode 100644 index 000000000..bfd44f725 --- /dev/null +++ b/abi-bindings/go/validator-manager/ERC20TokenStakingManager/ERC20TokenStakingManager.go @@ -0,0 +1,3257 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokenstakingmanager + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ConversionData is an auto generated low-level Go binding around an user-defined struct. +type ConversionData struct { + SubnetID [32]byte + ValidatorManagerBlockchainID [32]byte + ValidatorManagerAddress common.Address + InitialValidators []InitialValidator +} + +// Delegator is an auto generated low-level Go binding around an user-defined struct. +type Delegator struct { + Status uint8 + Owner common.Address + ValidationID [32]byte + Weight uint64 + StartTime uint64 + StartingNonce uint64 + EndingNonce uint64 +} + +// InitialValidator is an auto generated low-level Go binding around an user-defined struct. +type InitialValidator struct { + NodeID []byte + BlsPublicKey []byte + Weight uint64 +} + +// PChainOwner is an auto generated low-level Go binding around an user-defined struct. +type PChainOwner struct { + Threshold uint32 + Addresses []common.Address +} + +// PoSValidatorInfo is an auto generated low-level Go binding around an user-defined struct. +type PoSValidatorInfo struct { + Owner common.Address + DelegationFeeBips uint16 + MinStakeDuration uint64 + UptimeSeconds uint64 +} + +// StakingManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type StakingManagerSettings struct { + Manager common.Address + MinimumStakeAmount *big.Int + MaximumStakeAmount *big.Int + MinimumStakeDuration uint64 + MinimumDelegationFeeBips uint16 + MaximumStakeMultiplier uint8 + WeightToValueFactor *big.Int + RewardCalculator common.Address + UptimeBlockchainID [32]byte +} + +// ValidatorMessagesValidationPeriod is an auto generated low-level Go binding around an user-defined struct. +type ValidatorMessagesValidationPeriod struct { + SubnetID [32]byte + NodeID []byte + BlsPublicKey []byte + RegistrationExpiry uint64 + RemainingBalanceOwner PChainOwner + DisableOwner PChainOwner + Weight uint64 +} + +// ERC20TokenStakingManagerMetaData contains all meta data concerning the ERC20TokenStakingManager contract. +var ERC20TokenStakingManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"enumICMInitializable\",\"name\":\"init\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"DelegatorIneligibleForRewards\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"}],\"name\":\"InvalidDelegationFee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"InvalidDelegationID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumDelegatorStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"InvalidDelegatorStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"}],\"name\":\"InvalidMinStakeDuration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InvalidRewardRecipient\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"stakeAmount\",\"type\":\"uint256\"}],\"name\":\"InvalidStakeAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\"}],\"name\":\"InvalidStakeMultiplier\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uptimeBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"InvalidUptimeBlockchainID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumValidatorStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"InvalidValidatorStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWarpMessage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"InvalidWarpOriginSenderAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceChainID\",\"type\":\"bytes32\"}],\"name\":\"InvalidWarpSourceChainID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"newValidatorWeight\",\"type\":\"uint64\"}],\"name\":\"MaxWeightExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"endTime\",\"type\":\"uint64\"}],\"name\":\"MinStakeDurationNotPassed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"UnauthorizedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expectedValidationID\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedValidationID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"ValidatorIneligibleForRewards\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"ValidatorNotPoS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroWeightToValueFactor\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startTime\",\"type\":\"uint256\"}],\"name\":\"CompletedDelegatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"}],\"name\":\"CompletedDelegatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DelegatorRewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"}],\"name\":\"DelegatorRewardRecipientChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegatorAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"validatorWeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"delegatorWeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"setWeightMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InitiatedDelegatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"InitiatedDelegatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InitiatedStakingValidatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"uptime\",\"type\":\"uint64\"}],\"name\":\"UptimeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ValidatorRewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"}],\"name\":\"ValidatorRewardRecipientChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BIPS_CONVERSION_FACTOR\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ERC20_STAKING_MANAGER_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_DELEGATION_FEE_BIPS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_STAKE_MULTIPLIER_LIMIT\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STAKING_MANAGER_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WARP_MESSENGER\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"changeDelegatorRewardRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"changeValidatorRewardRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"claimDelegationFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeDelegatorRegistration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRemoval\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"erc20\",\"outputs\":[{\"internalType\":\"contractIERC20Mintable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"forceInitiateDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"forceInitiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"getDelegatorInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"enumDelegatorStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"startTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"startingNonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"endingNonce\",\"type\":\"uint64\"}],\"internalType\":\"structDelegator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"getDelegatorRewardInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStakingManagerSettings\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIValidatorManager\",\"name\":\"manager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minimumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"minimumStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"minimumDelegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"weightToValueFactor\",\"type\":\"uint256\"},{\"internalType\":\"contractIRewardCalculator\",\"name\":\"rewardCalculator\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uptimeBlockchainID\",\"type\":\"bytes32\"}],\"internalType\":\"structStakingManagerSettings\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"getStakingValidator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"uptimeSeconds\",\"type\":\"uint64\"}],\"internalType\":\"structPoSValidatorInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"getValidatorRewardInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIValidatorManager\",\"name\":\"manager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minimumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"minimumStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"minimumDelegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"weightToValueFactor\",\"type\":\"uint256\"},{\"internalType\":\"contractIRewardCalculator\",\"name\":\"rewardCalculator\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uptimeBlockchainID\",\"type\":\"bytes32\"}],\"internalType\":\"structStakingManagerSettings\",\"name\":\"settings\",\"type\":\"tuple\"},{\"internalType\":\"contractIERC20Mintable\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"delegationAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"initiateDelegatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initiateDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"stakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"initiateValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"resendUpdateDelegator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"submitUptimeProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"valueToWeight\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"weightToValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b506040516144f63803806144f683398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b6143a98061014d5f395ff3fe608060405234801561000f575f80fd5b50600436106101d1575f3560e01c80637e65f4da116100fe578063b2c1712e1161009e578063cd236e7f1161006e578063cd236e7f14610495578063e24b2680146104a8578063e4a63c40146104bb578063fb8b11dd146104cf575f80fd5b8063b2c1712e1461044c578063b5c934981461045f578063b771b3bc14610472578063caa7187414610480575f80fd5b80639681d940116100d95780639681d940146103f4578063a3a65e4814610407578063a9778a7a146102f3578063af1dd66c1461041a575f80fd5b80637e65f4da146103bb5780638ef34c98146103ce57806393e24598146103e1575f80fd5b80632aa566381161017457806360ad77841161014457806360ad77841461032f5780636206585614610342578063785e9e86146103635780637a63ad8514610394575f80fd5b80632aa56638146102b55780632e2194d8146102c857806335455ded146102f357806353a133381461030f575f80fd5b8063245dafcb116101af578063245dafcb1461021c57806325e1c7761461022f5780632674874b1461024257806327bf60cd146102a2575f80fd5b806313409645146101d5578063151d30d1146101ea5780631667956414610209575b5f80fd5b6101e86101e336600461384e565b6104e2565b005b6101f2600a81565b60405160ff90911681526020015b60405180910390f35b6101e8610217366004613885565b610822565b6101e861022a3660046138c0565b610833565b6101e861023d36600461384e565b610af7565b6102556102503660046138c0565b610bd5565b6040805182516001600160a01b0316815260208084015161ffff1690820152828201516001600160401b039081169282019290925260609283015190911691810191909152608001610200565b6101e86102b0366004613885565b610c61565b6101e86102c3366004613885565b610c6c565b6102db6102d63660046138c0565b610c7c565b6040516001600160401b039091168152602001610200565b6102fc61271081565b60405161ffff9091168152602001610200565b61032261031d3660046138c0565b610cd0565b60405161020091906138ff565b6101e861033d36600461384e565b610dbd565b61035561035036600461398d565b6110df565b604051908152602001610200565b5f80516020614334833981519152546001600160a01b03165b6040516001600160a01b039091168152602001610200565b6103557fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60081565b6103556103c9366004613ba8565b6110ff565b6101e86103dc366004613c87565b61113c565b6101e86103ef3660046138c0565b61121e565b610355610402366004613cb5565b611337565b610355610415366004613cb5565b6114d8565b61042d6104283660046138c0565b611550565b604080516001600160a01b039093168352602083019190915201610200565b6101e861045a366004613885565b61158c565b6101e861046d366004613cce565b611597565b61037c6005600160991b0181565b6104886116a5565b6040516102009190613d01565b6103556104a3366004613da2565b611781565b61042d6104b63660046138c0565b6117b5565b6103555f8051602061433483398151915281565b6101e86104dd366004613c87565b6117f1565b6104ea6118b9565b5f6104f36118f0565b5f848152600882016020526040808220815160e0810190925280549394509192909190829060ff16600381111561052c5761052c6138d7565b600381111561053d5761053d6138d7565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015290506003815160038111156105b6576105b66138d7565b146105e0578051604051633b0d540d60e21b81526105d79190600401613dd8565b60405180910390fd5b81546040828101519051636af907fb60e11b815260048101919091525f916001600160a01b03169063d5f20ff6906024015f60405180830381865afa15801561062b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106529190810190613e6b565b9050600483546040808501519051636af907fb60e11b81526001600160a01b039092169163d5f20ff69161068c9160040190815260200190565b5f60405180830381865afa1580156106a6573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106cd9190810190613e6b565b5160058111156106df576106df6138d7565b1415801561070657508160c001516001600160401b031681608001516001600160401b0316105b156107fc57825460405163338587c560e21b815263ffffffff861660048201525f9182916001600160a01b039091169063ce161f149060240160408051808303815f875af115801561075a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061077e9190613f4a565b91509150818460400151146107b75781846040015160405163fee3144560e01b81526004016105d7929190918252602082015260400190565b806001600160401b03168460c001516001600160401b031611156107f957604051632e19bc2d60e11b81526001600160401b03821660048201526024016105d7565b50505b61080585611914565b50505061081e60015f8051602061435483398151915255565b5050565b61082d838383611b58565b50505050565b5f61083c6118f0565b5f838152600882016020526040808220815160e0810190925280549394509192909190829060ff166003811115610875576108756138d7565b6003811115610886576108866138d7565b8152815461010090046001600160a01b0316602082015260018083015460408301526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c090910152909150815160038111156108ff576108ff6138d7565b14158015610920575060038151600381111561091d5761091d6138d7565b14155b15610941578051604051633b0d540d60e21b81526105d79190600401613dd8565b81546040828101519051636af907fb60e11b815260048101919091525f916001600160a01b03169063d5f20ff6906024015f60405180830381865afa15801561098c573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109b39190810190613e6b565b905080606001516001600160401b03165f036109e5576040516339b894f960e21b8152600481018590526024016105d7565b604080830151606083015160a0840151925163854a893f60e01b81526005600160991b019363ee5b48eb9373__$16907f4f2c19a387278bf4c8803bf9f1c2$__9363854a893f93610a5393906004019283526001600160401b03918216602084015216604082015260600190565b5f60405180830381865af4158015610a6d573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a949190810190613f6d565b6040518263ffffffff1660e01b8152600401610ab09190613fc9565b6020604051808303815f875af1158015610acc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610af09190613fdb565b5050505050565b610b0082611dfd565b610b20576040516330efa98b60e01b8152600481018390526024016105d7565b5f610b296118f0565b54604051636af907fb60e11b8152600481018590526001600160a01b039091169063d5f20ff6906024015f60405180830381865afa158015610b6d573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610b949190810190613e6b565b5190506002816005811115610bab57610bab6138d7565b14610bcb578060405163170cc93360e21b81526004016105d79190613ff2565b61082d8383611e26565b604080516080810182525f808252602082018190529181018290526060810191909152610c006118f0565b5f9283526007016020908152604092839020835160808101855281546001600160a01b038116825261ffff600160a01b820416938201939093526001600160401b03600160b01b909304831694810194909452600101541660608301525090565b61082d838383612090565b610c778383836124b1565b505050565b5f80610c866118f0565b60040154610c949084614020565b9050801580610ca957506001600160401b0381115b15610cca5760405163222d164360e21b8152600481018490526024016105d7565b92915050565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152610d106118f0565b5f838152600891909101602052604090819020815160e081019092528054829060ff166003811115610d4457610d446138d7565b6003811115610d5557610d556138d7565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015292915050565b5f610dc66118f0565b5f848152600882016020526040808220815160e0810190925280549394509192909190829060ff166003811115610dff57610dff6138d7565b6003811115610e1057610e106138d7565b8152815461010090046001600160a01b03908116602083015260018301546040808401919091526002909301546001600160401b038082166060850152600160401b820481166080850152600160801b8204811660a0850152600160c01b9091041660c0909201919091528282015185549251636af907fb60e11b815260048101829052939450925f929091169063d5f20ff6906024015f60405180830381865afa158015610ec1573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ee89190810190613e6b565b9050600183516003811115610eff57610eff6138d7565b14610f20578251604051633b0d540d60e21b81526105d79190600401613dd8565b600481516005811115610f3557610f356138d7565b03610f4b57610f4386611914565b505050505050565b8260a001516001600160401b031681608001516001600160401b0316101561105357835460405163338587c560e21b815263ffffffff871660048201525f9182916001600160a01b039091169063ce161f149060240160408051808303815f875af1158015610fbc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fe09190613f4a565b9150915081841461100e5760405163fee3144560e01b815260048101839052602481018590526044016105d7565b8460a001516001600160401b0316816001600160401b0316101561105057604051632e19bc2d60e11b81526001600160401b03821660048201526024016105d7565b50505b5f868152600885016020908152604091829020805460ff1916600290811782550180546001600160401b034216600160401b81026fffffffffffffffff000000000000000019909216919091179091559151918252839188917f3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa910160405180910390a3505050505050565b5f6110e86118f0565b60040154610cca906001600160401b03841661403f565b5f6111086118b9565b61111889898989898989896124dc565b905061113060015f8051602061435483398151915255565b98975050505050505050565b5f6111456118f0565b90506001600160a01b0382166111795760405163caa903f960e01b81526001600160a01b03831660048201526024016105d7565b5f8381526007820160205260409020546001600160a01b031633146111bf57335b604051636e2ccd7560e11b81526001600160a01b0390911660048201526024016105d7565b5f838152600c8201602052604080822080546001600160a01b038681166001600160a01b0319831681179093559251921692839287917f28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c3391a450505050565b5f6112276118f0565b8054604051636af907fb60e11b8152600481018590529192505f916001600160a01b039091169063d5f20ff6906024015f60405180830381865afa158015611271573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526112989190810190613e6b565b51905060048160058111156112af576112af6138d7565b146112cf578060405163170cc93360e21b81526004016105d79190613ff2565b5f8381526007830160205260409020546001600160a01b031633146112f4573361119a565b5f838152600c830160205260409020546001600160a01b03168061132d57505f8381526007830160205260409020546001600160a01b03165b61082d8185612813565b5f6113406118b9565b5f6113496118f0565b805460405163025a076560e61b815263ffffffff861660048201529192505f916001600160a01b0390911690639681d940906024016020604051808303815f875af115801561139a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113be9190613fdb565b8254604051636af907fb60e11b8152600481018390529192505f916001600160a01b039091169063d5f20ff6906024015f60405180830381865afa158015611408573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261142f9190810190613e6b565b905061143a82611dfd565b611448575091506114bd9050565b5f828152600784016020908152604080832054600c8701909252909120546001600160a01b0391821691168061147b5750805b600483516005811115611490576114906138d7565b0361149f5761149f8185612813565b6114b5826114b085604001516110df565b612887565b509193505050505b6114d360015f8051602061435483398151915255565b919050565b5f6114e16118f0565b54604051631474cbc960e31b815263ffffffff841660048201526001600160a01b039091169063a3a65e48906024016020604051808303815f875af115801561152c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cca9190613fdb565b5f805f61155b6118f0565b5f948552600a810160209081526040808720546009909301909152909420546001600160a01b039094169492505050565b610c778383836128aa565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156115db5750825b90505f826001600160401b031660011480156115f65750303b155b905081158015611604575080155b156116225760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561164c57845460ff60401b1916600160401b1785555b61165687876128d5565b831561169c57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b60408051610120810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052906116f56118f0565b604080516101208101825282546001600160a01b0390811682526001840154602083015260028401549282019290925260038301546001600160401b0381166060830152600160401b810461ffff166080830152600160501b900460ff1660a0820152600483015460c0820152600583015490911660e082015260069091015461010082015292915050565b5f61178a6118b9565b611796843385856128ef565b90506117ae60015f8051602061435483398151915255565b9392505050565b5f805f6117c06118f0565b5f948552600c81016020908152604080872054600b909301909152909420546001600160a01b039094169492505050565b6001600160a01b0381166118235760405163caa903f960e01b81526001600160a01b03821660048201526024016105d7565b5f61182c6118f0565b5f8481526008820160205260409020549091506001600160a01b0361010090910416331461185a573361119a565b5f838152600a8201602052604080822080546001600160a01b038681166001600160a01b0319831681179093559251921692839287917f6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e00591a450505050565b5f805160206143548339815191528054600119016118ea57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b7fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60090565b5f61191d6118f0565b5f838152600882016020526040808220815160e0810190925280549394509192909190829060ff166003811115611956576119566138d7565b6003811115611967576119676138d7565b815281546001600160a01b03610100909104811660208084019190915260018401546040808501919091526002909401546001600160401b038082166060860152600160401b820481166080860152600160801b8204811660a0860152600160c01b9091041660c09093019290925283830151865484516304e0efb360e11b8152945195965090949116926309c1df669260048083019391928290030181865afa158015611a17573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3b9190614056565b8260800151611a4a9190614071565b6001600160401b0316421015611a7e5760405163fb6ce63f60e01b81526001600160401b03421660048201526024016105d7565b5f848152600884016020908152604080832080546001600160a81b031916815560018101849055600201839055600a8601909152902080546001600160a01b031981169091556001600160a01b031680611ad9575060208201515b5f80611ae6838886612d39565b91509150611aff85602001516114b087606001516110df565b6040805183815260208101839052859189917f5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e910160405180910390a350505050505050565b60015f8051602061435483398151915255565b5f80611b626118f0565b8054604051635b73516560e11b8152600481018890529192506001600160a01b03169063b6e6a2ca906024015f604051808303815f87803b158015611ba5575f80fd5b505af1158015611bb7573d5f803e3d5ffd5b50508254604051636af907fb60e11b8152600481018990525f93506001600160a01b03909116915063d5f20ff6906024015f60405180830381865afa158015611c02573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c299190810190613e6b565b9050611c3486611dfd565b611c43576001925050506117ae565b5f8681526007830160205260409020546001600160a01b03163314611c68573361119a565b5f86815260078301602052604090205460c0820151611c9791600160b01b90046001600160401b031690614071565b6001600160401b03168160e001516001600160401b03161015611cde5760e081015160405163fb6ce63f60e01b81526001600160401b0390911660048201526024016105d7565b5f8515611cf657611cef8786611e26565b9050611d14565b505f8681526007830160205260409020600101546001600160401b03165b600583015460408301515f916001600160a01b031690634f22429f90611d39906110df565b60c086015160e0808801516040519185901b6001600160e01b031916825260048201939093526001600160401b0391821660248201819052604482015291811660648301528516608482015260a401602060405180830381865afa158015611da3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dc79190613fdb565b90508084600b015f8a81526020019081526020015f205f828254611deb9190614098565b90915550501515979650505050505050565b5f80611e076118f0565b5f938452600701602052505060409020546001600160a01b0316151590565b6040516306f8253560e41b815263ffffffff821660048201525f90819081906005600160991b0190636f825350906024015f60405180830381865afa158015611e71573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611e9891908101906140ab565b9150915080611eba57604051636b2f19e960e01b815260040160405180910390fd5b5f611ec36118f0565b6006810154845191925014611ef1578251604051636ba589a560e01b815260048101919091526024016105d7565b60208301516001600160a01b031615611f2d576020830151604051624de75d60e31b81526001600160a01b0390911660048201526024016105d7565b5f8073__$16907f4f2c19a387278bf4c8803bf9f1c2$__63088c246386604001516040518263ffffffff1660e01b8152600401611f6a9190613fc9565b6040805180830381865af4158015611f84573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fa89190613f4a565b91509150818814611fd65760405163fee3144560e01b815260048101839052602481018990526044016105d7565b5f8881526007840160205260409020600101546001600160401b039081169082161115612067575f888152600784016020908152604091829020600101805467ffffffffffffffff19166001600160401b038516908117909155915191825289917fec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435910160405180910390a2612085565b505f8781526007830160205260409020600101546001600160401b03165b979650505050505050565b5f8061209a6118f0565b5f868152600882016020526040808220815160e0810190925280549394509192909190829060ff1660038111156120d3576120d36138d7565b60038111156120e4576120e46138d7565b8152815461010090046001600160a01b03908116602083015260018301546040808401919091526002909301546001600160401b038082166060850152600160401b820481166080850152600160801b8204811660a0850152600160c01b9091041660c0909201919091528282015185549251636af907fb60e11b815260048101829052939450925f929091169063d5f20ff6906024015f60405180830381865afa158015612195573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526121bc9190810190613e6b565b90506002835160038111156121d3576121d36138d7565b146121f4578251604051633b0d540d60e21b81526105d79190600401613dd8565b60208301516001600160a01b03163314612290575f8281526007850160205260409020546001600160a01b0316331461222d573361119a565b5f82815260078501602052604090205460c082015161225c91600160b01b90046001600160401b031690614071565b6001600160401b03164210156122905760405163fb6ce63f60e01b81526001600160401b03421660048201526024016105d7565b5f888152600a850160205260409020546001600160a01b03166002825160058111156122be576122be6138d7565b0361245857600385015460808501516122e0916001600160401b031690614071565b6001600160401b03164210156123145760405163fb6ce63f60e01b81526001600160401b03421660048201526024016105d7565b8715612326576123248388611e26565b505b5f8981526008860160205260409020805460ff191660031790558454606085015160a08401516001600160a01b0390921691636610966991869161236a9190614151565b6040516001600160e01b031960e085901b16815260048101929092526001600160401b0316602482015260440160408051808303815f875af11580156123b2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123d69190614171565b505f8a8152600887016020526040812060020180546001600160401b03909316600160c01b026001600160c01b039093169290921790915561241985838c612e38565b9050838a7f5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf60405160405180910390a3151595506117ae945050505050565b60048251600581111561246d5761246d6138d7565b036124955761247d84828b612e38565b5061248789611914565b6001955050505050506117ae565b815160405163170cc93360e21b81526105d79190600401613ff2565b6124bc838383612090565b610c7757604051631036cf9160e11b8152600481018490526024016105d7565b5f806124e66118f0565b600381015490915061ffff600160401b9091048116908716108061250f575061271061ffff8716115b1561253357604051635f12e6c360e11b815261ffff871660048201526024016105d7565b60038101546001600160401b03908116908616101561256f576040516202a06d60e11b81526001600160401b03861660048201526024016105d7565b80600101548410806125845750806002015484115b156125a55760405163222d164360e21b8152600481018590526024016105d7565b6001600160a01b0383166125d75760405163caa903f960e01b81526001600160a01b03841660048201526024016105d7565b5f6125e185613072565b90505f6125ed82610c7c565b90505f835f015f9054906101000a90046001600160a01b03166001600160a01b0316639cb7624e8e8e8e8e876040518663ffffffff1660e01b8152600401612639959493929190614203565b6020604051808303815f875af1158015612655573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126799190613fdb565b90505f33905080856007015f8481526020019081526020015f205f015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555089856007015f8481526020019081526020015f205f0160146101000a81548161ffff021916908361ffff16021790555088856007015f8481526020019081526020015f205f0160166101000a8154816001600160401b0302191690836001600160401b031602179055505f856007015f8481526020019081526020015f206001015f6101000a8154816001600160401b0302191690836001600160401b031602179055508685600c015f8481526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001600160a01b0316827ff51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f8c8c8b6040516127fa9392919061ffff9390931683526001600160401b039190911660208301526001600160a01b0316604082015260600190565b60405180910390a3509c9b505050505050505050505050565b5f61281c6118f0565b5f838152600b820160205260408120805491905590915061283d8482613095565b836001600160a01b0316837f875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e48360405161287991815260200190565b60405180910390a350505050565b5f805160206143348339815191525461081e906001600160a01b03168383613102565b6128b5838383611b58565b610c7757604051635bff683f60e11b8152600481018490526024016105d7565b6128dd613161565b6128e6826131ac565b61081e8161322a565b5f806128f96118f0565b90505f6129086102d686613072565b905061291387611dfd565b612933576040516330efa98b60e01b8152600481018890526024016105d7565b6001600160a01b0384166129655760405163caa903f960e01b81526001600160a01b03851660048201526024016105d7565b8154604051636af907fb60e11b8152600481018990525f9182916001600160a01b039091169063d5f20ff6906024015f60405180830381865afa1580156129ae573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526129d59190810190613e6b565b9050828160a001516129e79190614071565b915083600301600a9054906101000a90046001600160401b03168160400151612a10919061426b565b6001600160401b0316826001600160401b03161115612a4d57604051636d51fe0560e11b81526001600160401b03831660048201526024016105d7565b508254604051636610966960e01b8152600481018a90526001600160401b03831660248201525f9182916001600160a01b039091169063661096699060440160408051808303815f875af1158015612aa7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612acb9190614171565b915091505f8a83604051602001612af992919091825260c01b6001600160c01b031916602082015260280190565b60408051601f1981840301815291815281516020928301205f81815260088a019093529120805491925060019160ff19168280021790555089866008015f8381526020019081526020015f205f0160016101000a8154816001600160a01b0302191690836001600160a01b031602179055508a866008015f8381526020019081526020015f206001018190555084866008015f8381526020019081526020015f206002015f6101000a8154816001600160401b0302191690836001600160401b031602179055505f866008015f8381526020019081526020015f2060020160086101000a8154816001600160401b0302191690836001600160401b0316021790555082866008015f8381526020019081526020015f2060020160106101000a8154816001600160401b0302191690836001600160401b031602179055505f866008015f8381526020019081526020015f2060020160186101000a8154816001600160401b0302191690836001600160401b031602179055508786600a015f8381526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168b827f77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d7786888a888f604051612d239594939291906001600160401b039586168152938516602085015291909316604083015260608201929092526001600160a01b0391909116608082015260a00190565b60405180910390a49a9950505050505050505050565b5f805f612d446118f0565b5f8681526009820160205260408120549192509081908015612e2a575f88815260098501602090815260408083208390558983526007870190915290205461271090612d9b90600160a01b900461ffff168361403f565b612da59190614020565b91508184600b015f8981526020019081526020015f205f828254612dc99190614098565b90915550612dd990508282614296565b9250612de58984613095565b886001600160a01b0316887f3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf6385604051612e2191815260200190565b60405180910390a35b509097909650945050505050565b5f80612e426118f0565b80546040808801519051636af907fb60e11b81529293505f926001600160a01b039092169163d5f20ff691612e7d9160040190815260200190565b5f60405180830381865afa158015612e97573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612ebe9190810190613e6b565b90505f600382516005811115612ed657612ed66138d7565b1480612ef45750600482516005811115612ef257612ef26138d7565b145b15612f04575060e0810151612f21565b600282516005811115612f1957612f196138d7565b036124955750425b86608001516001600160401b0316816001600160401b031611612f49575f93505050506117ae565b600583015460608801515f916001600160a01b031690634f22429f90612f6e906110df565b60c086015160808c01516040808e01515f90815260078b0160205281902060010154905160e086901b6001600160e01b031916815260048101949094526001600160401b0392831660248501529082166044840152818716606484015216608482015260a401602060405180830381865afa158015612fef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130139190613fdb565b90506001600160a01b03871661302b57876020015196505b5f8681526009850160209081526040808320849055600a90960190529390932080546001600160a01b0388166001600160a01b031990911617905550909150509392505050565b5f610cca825f80516020614334833981519152546001600160a01b031690613287565b5f5f8051602061433483398151915280546040516340c10f1960e01b81526001600160a01b038681166004830152602482018690529293509116906340c10f19906044015f604051808303815f87803b1580156130f0575f80fd5b505af115801561169c573d5f803e3d5ffd5b6040516001600160a01b03838116602483015260448201839052610c7791859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613293565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166131aa57604051631afcd79f60e31b815260040160405180910390fd5b565b6131b4613161565b6131bc6132f4565b6132276131cc60208301836142a9565b602083013560408401356131e6608086016060870161398d565b6131f660a08701608088016142c4565b61320660c0880160a089016142dd565b60c088013561321c6101008a0160e08b016142a9565b896101000135613304565b50565b613232613161565b5f805160206143348339815191526001600160a01b0382166132675760405163d92e233d60e01b815260040160405180910390fd5b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6117ae83338461357b565b5f6132a76001600160a01b038416836136de565b905080515f141580156132cb5750808060200190518101906132c991906142fd565b155b15610c7757604051635274afe760e01b81526001600160a01b03841660048201526024016105d7565b6132fc613161565b6131aa6136eb565b61330c613161565b5f6133156118f0565b905061ffff8616158061332d575061271061ffff8716115b1561335157604051635f12e6c360e11b815261ffff871660048201526024016105d7565b878911156133755760405163222d164360e21b8152600481018a90526024016105d7565b60ff851615806133885750600a60ff8616115b156133ab5760405163170db35960e31b815260ff861660048201526024016105d7565b6001600160a01b038a166133d25760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0383166133f95760405163d92e233d60e01b815260040160405180910390fd5b896001600160a01b03166309c1df666040518163ffffffff1660e01b8152600401602060405180830381865afa158015613435573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134599190614056565b6001600160401b0316876001600160401b03161015613495576040516202a06d60e11b81526001600160401b03881660048201526024016105d7565b835f036134b55760405163a733007160e01b815260040160405180910390fd5b816134d657604051632f6bd1db60e01b8152600481018390526024016105d7565b80546001600160a01b039a8b166001600160a01b031991821617825560018201999099556002810197909755600387018054600160501b60ff9096169590950267ffffffffffffffff60501b1961ffff909716600160401b0269ffffffffffffffffffff199096166001600160401b03909816979097179490941794909416949094179091556004840155600583018054929095169190931617909255600690910155565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa1580156135c1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135e59190613fdb565b90506135fc6001600160a01b0386168530866136f3565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015613640573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136649190613fdb565b90508181116136ca5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016105d7565b6136d48282614296565b9695505050505050565b60606117ae83835f61372c565b611b45613161565b6040516001600160a01b03848116602483015283811660448301526064820183905261082d9186918216906323b872dd9060840161312f565b6060814710156137515760405163cd78605960e01b81523060048201526024016105d7565b5f80856001600160a01b0316848660405161376c9190614318565b5f6040518083038185875af1925050503d805f81146137a6576040519150601f19603f3d011682016040523d82523d5f602084013e6137ab565b606091505b50915091506136d48683836060826137cb576137c682613812565b6117ae565b81511580156137e257506001600160a01b0384163b155b1561380b57604051639996b31560e01b81526001600160a01b03851660048201526024016105d7565b50806117ae565b8051156138225780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b803563ffffffff811681146114d3575f80fd5b5f806040838503121561385f575f80fd5b8235915061386f6020840161383b565b90509250929050565b8015158114613227575f80fd5b5f805f60608486031215613897575f80fd5b8335925060208401356138a981613878565b91506138b76040850161383b565b90509250925092565b5f602082840312156138d0575f80fd5b5035919050565b634e487b7160e01b5f52602160045260245ffd5b600481106138fb576138fb6138d7565b9052565b5f60e0820190506139118284516138eb565b60018060a01b0360208401511660208301526040830151604083015260608301516001600160401b0380821660608501528060808601511660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b6001600160401b0381168114613227575f80fd5b80356114d38161396e565b5f6020828403121561399d575f80fd5b81356117ae8161396e565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156139de576139de6139a8565b60405290565b60405161010081016001600160401b03811182821017156139de576139de6139a8565b604051601f8201601f191681016001600160401b0381118282101715613a2f57613a2f6139a8565b604052919050565b5f6001600160401b03821115613a4f57613a4f6139a8565b50601f01601f191660200190565b5f82601f830112613a6c575f80fd5b8135613a7f613a7a82613a37565b613a07565b818152846020838601011115613a93575f80fd5b816020850160208301375f918101602001919091529392505050565b6001600160a01b0381168114613227575f80fd5b80356114d381613aaf565b5f60408284031215613ade575f80fd5b613ae66139bc565b9050613af18261383b565b81526020808301356001600160401b0380821115613b0d575f80fd5b818501915085601f830112613b20575f80fd5b813581811115613b3257613b326139a8565b8060051b9150613b43848301613a07565b8181529183018401918481019088841115613b5c575f80fd5b938501935b83851015613b865784359250613b7683613aaf565b8282529385019390850190613b61565b808688015250505050505092915050565b803561ffff811681146114d3575f80fd5b5f805f805f805f80610100898b031215613bc0575f80fd5b88356001600160401b0380821115613bd6575f80fd5b613be28c838d01613a5d565b995060208b0135915080821115613bf7575f80fd5b613c038c838d01613a5d565b985060408b0135915080821115613c18575f80fd5b613c248c838d01613ace565b975060608b0135915080821115613c39575f80fd5b50613c468b828c01613ace565b955050613c5560808a01613b97565b9350613c6360a08a01613982565b925060c08901359150613c7860e08a01613ac3565b90509295985092959890939650565b5f8060408385031215613c98575f80fd5b823591506020830135613caa81613aaf565b809150509250929050565b5f60208284031215613cc5575f80fd5b6117ae8261383b565b5f80828403610140811215613ce1575f80fd5b61012080821215613cf0575f80fd5b8493508301359050613caa81613aaf565b81516001600160a01b031681526020808301519082015260408083015190820152606080830151610120830191613d42908401826001600160401b03169052565b506080830151613d58608084018261ffff169052565b5060a0830151613d6d60a084018260ff169052565b5060c083015160c083015260e0830151613d9260e08401826001600160a01b03169052565b5061010092830151919092015290565b5f805f60608486031215613db4575f80fd5b83359250602084013591506040840135613dcd81613aaf565b809150509250925092565b60208101610cca82846138eb565b8051600681106114d3575f80fd5b5f5b83811015613e0e578181015183820152602001613df6565b50505f910152565b5f82601f830112613e25575f80fd5b8151613e33613a7a82613a37565b818152846020838601011115613e47575f80fd5b613e58826020830160208701613df4565b949350505050565b80516114d38161396e565b5f60208284031215613e7b575f80fd5b81516001600160401b0380821115613e91575f80fd5b908301906101008286031215613ea5575f80fd5b613ead6139e4565b613eb683613de6565b8152602083015182811115613ec9575f80fd5b613ed587828601613e16565b602083015250613ee760408401613e60565b6040820152613ef860608401613e60565b6060820152613f0960808401613e60565b6080820152613f1a60a08401613e60565b60a0820152613f2b60c08401613e60565b60c0820152613f3c60e08401613e60565b60e082015295945050505050565b5f8060408385031215613f5b575f80fd5b825191506020830151613caa8161396e565b5f60208284031215613f7d575f80fd5b81516001600160401b03811115613f92575f80fd5b613e5884828501613e16565b5f8151808452613fb5816020860160208601613df4565b601f01601f19169290920160200192915050565b602081525f6117ae6020830184613f9e565b5f60208284031215613feb575f80fd5b5051919050565b6020810160068310614006576140066138d7565b91905290565b634e487b7160e01b5f52601160045260245ffd5b5f8261403a57634e487b7160e01b5f52601260045260245ffd5b500490565b8082028115828204841417610cca57610cca61400c565b5f60208284031215614066575f80fd5b81516117ae8161396e565b6001600160401b038181168382160190808211156140915761409161400c565b5092915050565b80820180821115610cca57610cca61400c565b5f80604083850312156140bc575f80fd5b82516001600160401b03808211156140d2575f80fd5b90840190606082870312156140e5575f80fd5b604051606081018181108382111715614100576141006139a8565b60405282518152602083015161411581613aaf565b602082015260408301518281111561412b575f80fd5b61413788828601613e16565b6040830152508094505050506020830151613caa81613878565b6001600160401b038281168282160390808211156140915761409161400c565b5f8060408385031215614182575f80fd5b825161418d8161396e565b6020939093015192949293505050565b5f6040830163ffffffff8351168452602080840151604060208701528281518085526060880191506020830194505f92505b808310156141f85784516001600160a01b031682529383019360019290920191908301906141cf565b509695505050505050565b60a081525f61421560a0830188613f9e565b82810360208401526142278188613f9e565b9050828103604084015261423b818761419d565b9050828103606084015261424f818661419d565b9150506001600160401b03831660808301529695505050505050565b6001600160401b0381811683821602808216919082811461428e5761428e61400c565b505092915050565b81810381811115610cca57610cca61400c565b5f602082840312156142b9575f80fd5b81356117ae81613aaf565b5f602082840312156142d4575f80fd5b6117ae82613b97565b5f602082840312156142ed575f80fd5b813560ff811681146117ae575f80fd5b5f6020828403121561430d575f80fd5b81516117ae81613878565b5f8251614329818460208701613df4565b919091019291505056fe6e5bdfcce15e53c3406ea67bfce37dcd26f5152d5492824e43fd5e3c8ac5ab009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a264697066735822122053f03ee830005067e3c3bda103ccce9ea2ec6aaa07f706f751386de9f10c475764736f6c63430008190033", +} + +// ERC20TokenStakingManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenStakingManagerMetaData.ABI instead. +var ERC20TokenStakingManagerABI = ERC20TokenStakingManagerMetaData.ABI + +// ERC20TokenStakingManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenStakingManagerMetaData.Bin instead. +var ERC20TokenStakingManagerBin = ERC20TokenStakingManagerMetaData.Bin + +// DeployERC20TokenStakingManager deploys a new Ethereum contract, binding an instance of ERC20TokenStakingManager to it. +func DeployERC20TokenStakingManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *ERC20TokenStakingManager, error) { + parsed, err := ERC20TokenStakingManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + validatorMessagesAddr, _, _, _ := DeployValidatorMessages(auth, backend) + ERC20TokenStakingManagerBin = strings.ReplaceAll(ERC20TokenStakingManagerBin, "__$16907f4f2c19a387278bf4c8803bf9f1c2$__", validatorMessagesAddr.String()[2:]) + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20TokenStakingManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenStakingManager{ERC20TokenStakingManagerCaller: ERC20TokenStakingManagerCaller{contract: contract}, ERC20TokenStakingManagerTransactor: ERC20TokenStakingManagerTransactor{contract: contract}, ERC20TokenStakingManagerFilterer: ERC20TokenStakingManagerFilterer{contract: contract}}, nil +} + +// ERC20TokenStakingManager is an auto generated Go binding around an Ethereum contract. +type ERC20TokenStakingManager struct { + ERC20TokenStakingManagerCaller // Read-only binding to the contract + ERC20TokenStakingManagerTransactor // Write-only binding to the contract + ERC20TokenStakingManagerFilterer // Log filterer for contract events +} + +// ERC20TokenStakingManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenStakingManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenStakingManagerSession struct { + Contract *ERC20TokenStakingManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenStakingManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenStakingManagerCallerSession struct { + Contract *ERC20TokenStakingManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenStakingManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenStakingManagerTransactorSession struct { + Contract *ERC20TokenStakingManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenStakingManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenStakingManagerRaw struct { + Contract *ERC20TokenStakingManager // Generic contract binding to access the raw methods on +} + +// ERC20TokenStakingManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerCallerRaw struct { + Contract *ERC20TokenStakingManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenStakingManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerTransactorRaw struct { + Contract *ERC20TokenStakingManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenStakingManager creates a new instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManager(address common.Address, backend bind.ContractBackend) (*ERC20TokenStakingManager, error) { + contract, err := bindERC20TokenStakingManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManager{ERC20TokenStakingManagerCaller: ERC20TokenStakingManagerCaller{contract: contract}, ERC20TokenStakingManagerTransactor: ERC20TokenStakingManagerTransactor{contract: contract}, ERC20TokenStakingManagerFilterer: ERC20TokenStakingManagerFilterer{contract: contract}}, nil +} + +// NewERC20TokenStakingManagerCaller creates a new read-only instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenStakingManagerCaller, error) { + contract, err := bindERC20TokenStakingManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerCaller{contract: contract}, nil +} + +// NewERC20TokenStakingManagerTransactor creates a new write-only instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenStakingManagerTransactor, error) { + contract, err := bindERC20TokenStakingManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerTransactor{contract: contract}, nil +} + +// NewERC20TokenStakingManagerFilterer creates a new log filterer instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenStakingManagerFilterer, error) { + contract, err := bindERC20TokenStakingManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerFilterer{contract: contract}, nil +} + +// bindERC20TokenStakingManager binds a generic wrapper to an already deployed contract. +func bindERC20TokenStakingManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenStakingManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenStakingManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.contract.Transact(opts, method, params...) +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) BIPSCONVERSIONFACTOR(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "BIPS_CONVERSION_FACTOR") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) BIPSCONVERSIONFACTOR() (uint16, error) { + return _ERC20TokenStakingManager.Contract.BIPSCONVERSIONFACTOR(&_ERC20TokenStakingManager.CallOpts) +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) BIPSCONVERSIONFACTOR() (uint16, error) { + return _ERC20TokenStakingManager.Contract.BIPSCONVERSIONFACTOR(&_ERC20TokenStakingManager.CallOpts) +} + +// ERC20STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0xe4a63c40. +// +// Solidity: function ERC20_STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) ERC20STAKINGMANAGERSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "ERC20_STAKING_MANAGER_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ERC20STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0xe4a63c40. +// +// Solidity: function ERC20_STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ERC20STAKINGMANAGERSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.ERC20STAKINGMANAGERSTORAGELOCATION(&_ERC20TokenStakingManager.CallOpts) +} + +// ERC20STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0xe4a63c40. +// +// Solidity: function ERC20_STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) ERC20STAKINGMANAGERSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.ERC20STAKINGMANAGERSTORAGELOCATION(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) MAXIMUMDELEGATIONFEEBIPS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "MAXIMUM_DELEGATION_FEE_BIPS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) MAXIMUMSTAKEMULTIPLIERLIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "MAXIMUM_STAKE_MULTIPLIER_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_ERC20TokenStakingManager.CallOpts) +} + +// STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0x7a63ad85. +// +// Solidity: function STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) STAKINGMANAGERSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "STAKING_MANAGER_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0x7a63ad85. +// +// Solidity: function STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) STAKINGMANAGERSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.STAKINGMANAGERSTORAGELOCATION(&_ERC20TokenStakingManager.CallOpts) +} + +// STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0x7a63ad85. +// +// Solidity: function STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) STAKINGMANAGERSTORAGELOCATION() ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.STAKINGMANAGERSTORAGELOCATION(&_ERC20TokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) WARPMESSENGER() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.WARPMESSENGER(&_ERC20TokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.WARPMESSENGER(&_ERC20TokenStakingManager.CallOpts) +} + +// Erc20 is a free data retrieval call binding the contract method 0x785e9e86. +// +// Solidity: function erc20() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) Erc20(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "erc20") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Erc20 is a free data retrieval call binding the contract method 0x785e9e86. +// +// Solidity: function erc20() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) Erc20() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.Erc20(&_ERC20TokenStakingManager.CallOpts) +} + +// Erc20 is a free data retrieval call binding the contract method 0x785e9e86. +// +// Solidity: function erc20() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) Erc20() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.Erc20(&_ERC20TokenStakingManager.CallOpts) +} + +// GetDelegatorInfo is a free data retrieval call binding the contract method 0x53a13338. +// +// Solidity: function getDelegatorInfo(bytes32 delegationID) view returns((uint8,address,bytes32,uint64,uint64,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) GetDelegatorInfo(opts *bind.CallOpts, delegationID [32]byte) (Delegator, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "getDelegatorInfo", delegationID) + + if err != nil { + return *new(Delegator), err + } + + out0 := *abi.ConvertType(out[0], new(Delegator)).(*Delegator) + + return out0, err + +} + +// GetDelegatorInfo is a free data retrieval call binding the contract method 0x53a13338. +// +// Solidity: function getDelegatorInfo(bytes32 delegationID) view returns((uint8,address,bytes32,uint64,uint64,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) GetDelegatorInfo(delegationID [32]byte) (Delegator, error) { + return _ERC20TokenStakingManager.Contract.GetDelegatorInfo(&_ERC20TokenStakingManager.CallOpts, delegationID) +} + +// GetDelegatorInfo is a free data retrieval call binding the contract method 0x53a13338. +// +// Solidity: function getDelegatorInfo(bytes32 delegationID) view returns((uint8,address,bytes32,uint64,uint64,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) GetDelegatorInfo(delegationID [32]byte) (Delegator, error) { + return _ERC20TokenStakingManager.Contract.GetDelegatorInfo(&_ERC20TokenStakingManager.CallOpts, delegationID) +} + +// GetDelegatorRewardInfo is a free data retrieval call binding the contract method 0xaf1dd66c. +// +// Solidity: function getDelegatorRewardInfo(bytes32 delegationID) view returns(address, uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) GetDelegatorRewardInfo(opts *bind.CallOpts, delegationID [32]byte) (common.Address, *big.Int, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "getDelegatorRewardInfo", delegationID) + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// GetDelegatorRewardInfo is a free data retrieval call binding the contract method 0xaf1dd66c. +// +// Solidity: function getDelegatorRewardInfo(bytes32 delegationID) view returns(address, uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) GetDelegatorRewardInfo(delegationID [32]byte) (common.Address, *big.Int, error) { + return _ERC20TokenStakingManager.Contract.GetDelegatorRewardInfo(&_ERC20TokenStakingManager.CallOpts, delegationID) +} + +// GetDelegatorRewardInfo is a free data retrieval call binding the contract method 0xaf1dd66c. +// +// Solidity: function getDelegatorRewardInfo(bytes32 delegationID) view returns(address, uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) GetDelegatorRewardInfo(delegationID [32]byte) (common.Address, *big.Int, error) { + return _ERC20TokenStakingManager.Contract.GetDelegatorRewardInfo(&_ERC20TokenStakingManager.CallOpts, delegationID) +} + +// GetStakingManagerSettings is a free data retrieval call binding the contract method 0xcaa71874. +// +// Solidity: function getStakingManagerSettings() view returns((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) GetStakingManagerSettings(opts *bind.CallOpts) (StakingManagerSettings, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "getStakingManagerSettings") + + if err != nil { + return *new(StakingManagerSettings), err + } + + out0 := *abi.ConvertType(out[0], new(StakingManagerSettings)).(*StakingManagerSettings) + + return out0, err + +} + +// GetStakingManagerSettings is a free data retrieval call binding the contract method 0xcaa71874. +// +// Solidity: function getStakingManagerSettings() view returns((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) GetStakingManagerSettings() (StakingManagerSettings, error) { + return _ERC20TokenStakingManager.Contract.GetStakingManagerSettings(&_ERC20TokenStakingManager.CallOpts) +} + +// GetStakingManagerSettings is a free data retrieval call binding the contract method 0xcaa71874. +// +// Solidity: function getStakingManagerSettings() view returns((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) GetStakingManagerSettings() (StakingManagerSettings, error) { + return _ERC20TokenStakingManager.Contract.GetStakingManagerSettings(&_ERC20TokenStakingManager.CallOpts) +} + +// GetStakingValidator is a free data retrieval call binding the contract method 0x2674874b. +// +// Solidity: function getStakingValidator(bytes32 validationID) view returns((address,uint16,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) GetStakingValidator(opts *bind.CallOpts, validationID [32]byte) (PoSValidatorInfo, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "getStakingValidator", validationID) + + if err != nil { + return *new(PoSValidatorInfo), err + } + + out0 := *abi.ConvertType(out[0], new(PoSValidatorInfo)).(*PoSValidatorInfo) + + return out0, err + +} + +// GetStakingValidator is a free data retrieval call binding the contract method 0x2674874b. +// +// Solidity: function getStakingValidator(bytes32 validationID) view returns((address,uint16,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) GetStakingValidator(validationID [32]byte) (PoSValidatorInfo, error) { + return _ERC20TokenStakingManager.Contract.GetStakingValidator(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// GetStakingValidator is a free data retrieval call binding the contract method 0x2674874b. +// +// Solidity: function getStakingValidator(bytes32 validationID) view returns((address,uint16,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) GetStakingValidator(validationID [32]byte) (PoSValidatorInfo, error) { + return _ERC20TokenStakingManager.Contract.GetStakingValidator(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// GetValidatorRewardInfo is a free data retrieval call binding the contract method 0xe24b2680. +// +// Solidity: function getValidatorRewardInfo(bytes32 validationID) view returns(address, uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) GetValidatorRewardInfo(opts *bind.CallOpts, validationID [32]byte) (common.Address, *big.Int, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "getValidatorRewardInfo", validationID) + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// GetValidatorRewardInfo is a free data retrieval call binding the contract method 0xe24b2680. +// +// Solidity: function getValidatorRewardInfo(bytes32 validationID) view returns(address, uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) GetValidatorRewardInfo(validationID [32]byte) (common.Address, *big.Int, error) { + return _ERC20TokenStakingManager.Contract.GetValidatorRewardInfo(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// GetValidatorRewardInfo is a free data retrieval call binding the contract method 0xe24b2680. +// +// Solidity: function getValidatorRewardInfo(bytes32 validationID) view returns(address, uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) GetValidatorRewardInfo(validationID [32]byte) (common.Address, *big.Int, error) { + return _ERC20TokenStakingManager.Contract.GetValidatorRewardInfo(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) ValueToWeight(opts *bind.CallOpts, value *big.Int) (uint64, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "valueToWeight", value) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _ERC20TokenStakingManager.Contract.ValueToWeight(&_ERC20TokenStakingManager.CallOpts, value) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _ERC20TokenStakingManager.Contract.ValueToWeight(&_ERC20TokenStakingManager.CallOpts, value) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) view returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) WeightToValue(opts *bind.CallOpts, weight uint64) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "weightToValue", weight) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) view returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _ERC20TokenStakingManager.Contract.WeightToValue(&_ERC20TokenStakingManager.CallOpts, weight) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) view returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _ERC20TokenStakingManager.Contract.WeightToValue(&_ERC20TokenStakingManager.CallOpts, weight) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address rewardRecipient) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ChangeDelegatorRewardRecipient(opts *bind.TransactOpts, delegationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "changeDelegatorRewardRecipient", delegationID, rewardRecipient) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address rewardRecipient) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ChangeDelegatorRewardRecipient(delegationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ChangeDelegatorRewardRecipient(&_ERC20TokenStakingManager.TransactOpts, delegationID, rewardRecipient) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address rewardRecipient) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ChangeDelegatorRewardRecipient(delegationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ChangeDelegatorRewardRecipient(&_ERC20TokenStakingManager.TransactOpts, delegationID, rewardRecipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address rewardRecipient) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ChangeValidatorRewardRecipient(opts *bind.TransactOpts, validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "changeValidatorRewardRecipient", validationID, rewardRecipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address rewardRecipient) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ChangeValidatorRewardRecipient(validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ChangeValidatorRewardRecipient(&_ERC20TokenStakingManager.TransactOpts, validationID, rewardRecipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address rewardRecipient) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ChangeValidatorRewardRecipient(validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ChangeValidatorRewardRecipient(&_ERC20TokenStakingManager.TransactOpts, validationID, rewardRecipient) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ClaimDelegationFees(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "claimDelegationFees", validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ClaimDelegationFees(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ClaimDelegationFees(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteDelegatorRegistration(opts *bind.TransactOpts, delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeDelegatorRegistration", delegationID, messageIndex) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteDelegatorRegistration(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteDelegatorRegistration(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeDelegatorRemoval", delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteDelegatorRemoval(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteDelegatorRemoval(&_ERC20TokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteDelegatorRemoval(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteDelegatorRemoval(&_ERC20TokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteValidatorRemoval(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeValidatorRemoval", messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRemoval(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRemoval(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ForceInitiateDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "forceInitiateDelegatorRemoval", delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ForceInitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ForceInitiateDelegatorRemoval(&_ERC20TokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ForceInitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ForceInitiateDelegatorRemoval(&_ERC20TokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ForceInitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "forceInitiateValidatorRemoval", validationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ForceInitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ForceInitiateValidatorRemoval(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ForceInitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ForceInitiateValidatorRemoval(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// Initialize is a paid mutator transaction binding the contract method 0xb5c93498. +// +// Solidity: function initialize((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) Initialize(opts *bind.TransactOpts, settings StakingManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initialize", settings, token) +} + +// Initialize is a paid mutator transaction binding the contract method 0xb5c93498. +// +// Solidity: function initialize((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) Initialize(settings StakingManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.Initialize(&_ERC20TokenStakingManager.TransactOpts, settings, token) +} + +// Initialize is a paid mutator transaction binding the contract method 0xb5c93498. +// +// Solidity: function initialize((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) Initialize(settings StakingManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.Initialize(&_ERC20TokenStakingManager.TransactOpts, settings, token) +} + +// InitiateDelegatorRegistration is a paid mutator transaction binding the contract method 0xcd236e7f. +// +// Solidity: function initiateDelegatorRegistration(bytes32 validationID, uint256 delegationAmount, address rewardRecipient) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitiateDelegatorRegistration(opts *bind.TransactOpts, validationID [32]byte, delegationAmount *big.Int, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initiateDelegatorRegistration", validationID, delegationAmount, rewardRecipient) +} + +// InitiateDelegatorRegistration is a paid mutator transaction binding the contract method 0xcd236e7f. +// +// Solidity: function initiateDelegatorRegistration(bytes32 validationID, uint256 delegationAmount, address rewardRecipient) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitiateDelegatorRegistration(validationID [32]byte, delegationAmount *big.Int, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, validationID, delegationAmount, rewardRecipient) +} + +// InitiateDelegatorRegistration is a paid mutator transaction binding the contract method 0xcd236e7f. +// +// Solidity: function initiateDelegatorRegistration(bytes32 validationID, uint256 delegationAmount, address rewardRecipient) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitiateDelegatorRegistration(validationID [32]byte, delegationAmount *big.Int, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, validationID, delegationAmount, rewardRecipient) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitiateDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initiateDelegatorRemoval", delegationID, includeUptimeProof, messageIndex) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateDelegatorRemoval(&_ERC20TokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateDelegatorRemoval(&_ERC20TokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x7e65f4da. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint16 delegationFeeBips, uint64 minStakeDuration, uint256 stakeAmount, address rewardRecipient) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitiateValidatorRegistration(opts *bind.TransactOpts, nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, delegationFeeBips uint16, minStakeDuration uint64, stakeAmount *big.Int, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initiateValidatorRegistration", nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDuration, stakeAmount, rewardRecipient) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x7e65f4da. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint16 delegationFeeBips, uint64 minStakeDuration, uint256 stakeAmount, address rewardRecipient) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, delegationFeeBips uint16, minStakeDuration uint64, stakeAmount *big.Int, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDuration, stakeAmount, rewardRecipient) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x7e65f4da. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint16 delegationFeeBips, uint64 minStakeDuration, uint256 stakeAmount, address rewardRecipient) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, delegationFeeBips uint16, minStakeDuration uint64, stakeAmount *big.Int, rewardRecipient common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDuration, stakeAmount, rewardRecipient) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initiateValidatorRemoval", validationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateValidatorRemoval(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitiateValidatorRemoval(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ResendUpdateDelegator(opts *bind.TransactOpts, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "resendUpdateDelegator", delegationID) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ResendUpdateDelegator(delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendUpdateDelegator(&_ERC20TokenStakingManager.TransactOpts, delegationID) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ResendUpdateDelegator(delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendUpdateDelegator(&_ERC20TokenStakingManager.TransactOpts, delegationID) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) SubmitUptimeProof(opts *bind.TransactOpts, validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "submitUptimeProof", validationID, messageIndex) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) SubmitUptimeProof(validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.SubmitUptimeProof(&_ERC20TokenStakingManager.TransactOpts, validationID, messageIndex) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) SubmitUptimeProof(validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.SubmitUptimeProof(&_ERC20TokenStakingManager.TransactOpts, validationID, messageIndex) +} + +// ERC20TokenStakingManagerCompletedDelegatorRegistrationIterator is returned from FilterCompletedDelegatorRegistration and is used to iterate over the raw logs and unpacked data for CompletedDelegatorRegistration events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerCompletedDelegatorRegistrationIterator struct { + Event *ERC20TokenStakingManagerCompletedDelegatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerCompletedDelegatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerCompletedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerCompletedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerCompletedDelegatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerCompletedDelegatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerCompletedDelegatorRegistration represents a CompletedDelegatorRegistration event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerCompletedDelegatorRegistration struct { + DelegationID [32]byte + ValidationID [32]byte + StartTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedDelegatorRegistration is a free log retrieval operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterCompletedDelegatorRegistration(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*ERC20TokenStakingManagerCompletedDelegatorRegistrationIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "CompletedDelegatorRegistration", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerCompletedDelegatorRegistrationIterator{contract: _ERC20TokenStakingManager.contract, event: "CompletedDelegatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchCompletedDelegatorRegistration is a free log subscription operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchCompletedDelegatorRegistration(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerCompletedDelegatorRegistration, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "CompletedDelegatorRegistration", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerCompletedDelegatorRegistration) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRegistration", 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 +} + +// ParseCompletedDelegatorRegistration is a log parse operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseCompletedDelegatorRegistration(log types.Log) (*ERC20TokenStakingManagerCompletedDelegatorRegistration, error) { + event := new(ERC20TokenStakingManagerCompletedDelegatorRegistration) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerCompletedDelegatorRemovalIterator is returned from FilterCompletedDelegatorRemoval and is used to iterate over the raw logs and unpacked data for CompletedDelegatorRemoval events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerCompletedDelegatorRemovalIterator struct { + Event *ERC20TokenStakingManagerCompletedDelegatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerCompletedDelegatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerCompletedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerCompletedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerCompletedDelegatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerCompletedDelegatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerCompletedDelegatorRemoval represents a CompletedDelegatorRemoval event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerCompletedDelegatorRemoval struct { + DelegationID [32]byte + ValidationID [32]byte + Rewards *big.Int + Fees *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedDelegatorRemoval is a free log retrieval operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterCompletedDelegatorRemoval(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*ERC20TokenStakingManagerCompletedDelegatorRemovalIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "CompletedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerCompletedDelegatorRemovalIterator{contract: _ERC20TokenStakingManager.contract, event: "CompletedDelegatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchCompletedDelegatorRemoval is a free log subscription operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchCompletedDelegatorRemoval(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerCompletedDelegatorRemoval, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "CompletedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerCompletedDelegatorRemoval) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRemoval", 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 +} + +// ParseCompletedDelegatorRemoval is a log parse operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseCompletedDelegatorRemoval(log types.Log) (*ERC20TokenStakingManagerCompletedDelegatorRemoval, error) { + event := new(ERC20TokenStakingManagerCompletedDelegatorRemoval) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerDelegatorRewardClaimedIterator is returned from FilterDelegatorRewardClaimed and is used to iterate over the raw logs and unpacked data for DelegatorRewardClaimed events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRewardClaimedIterator struct { + Event *ERC20TokenStakingManagerDelegatorRewardClaimed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerDelegatorRewardClaimedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerDelegatorRewardClaimedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerDelegatorRewardClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerDelegatorRewardClaimed represents a DelegatorRewardClaimed event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRewardClaimed struct { + DelegationID [32]byte + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRewardClaimed is a free log retrieval operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterDelegatorRewardClaimed(opts *bind.FilterOpts, delegationID [][32]byte, recipient []common.Address) (*ERC20TokenStakingManagerDelegatorRewardClaimedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "DelegatorRewardClaimed", delegationIDRule, recipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerDelegatorRewardClaimedIterator{contract: _ERC20TokenStakingManager.contract, event: "DelegatorRewardClaimed", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRewardClaimed is a free log subscription operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchDelegatorRewardClaimed(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerDelegatorRewardClaimed, delegationID [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "DelegatorRewardClaimed", delegationIDRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerDelegatorRewardClaimed) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRewardClaimed", 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 +} + +// ParseDelegatorRewardClaimed is a log parse operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseDelegatorRewardClaimed(log types.Log) (*ERC20TokenStakingManagerDelegatorRewardClaimed, error) { + event := new(ERC20TokenStakingManagerDelegatorRewardClaimed) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRewardClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerDelegatorRewardRecipientChangedIterator is returned from FilterDelegatorRewardRecipientChanged and is used to iterate over the raw logs and unpacked data for DelegatorRewardRecipientChanged events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRewardRecipientChangedIterator struct { + Event *ERC20TokenStakingManagerDelegatorRewardRecipientChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerDelegatorRewardRecipientChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerDelegatorRewardRecipientChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerDelegatorRewardRecipientChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerDelegatorRewardRecipientChanged represents a DelegatorRewardRecipientChanged event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRewardRecipientChanged struct { + DelegationID [32]byte + Recipient common.Address + OldRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRewardRecipientChanged is a free log retrieval operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterDelegatorRewardRecipientChanged(opts *bind.FilterOpts, delegationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (*ERC20TokenStakingManagerDelegatorRewardRecipientChangedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "DelegatorRewardRecipientChanged", delegationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerDelegatorRewardRecipientChangedIterator{contract: _ERC20TokenStakingManager.contract, event: "DelegatorRewardRecipientChanged", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRewardRecipientChanged is a free log subscription operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchDelegatorRewardRecipientChanged(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerDelegatorRewardRecipientChanged, delegationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "DelegatorRewardRecipientChanged", delegationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerDelegatorRewardRecipientChanged) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRewardRecipientChanged", 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 +} + +// ParseDelegatorRewardRecipientChanged is a log parse operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseDelegatorRewardRecipientChanged(log types.Log) (*ERC20TokenStakingManagerDelegatorRewardRecipientChanged, error) { + event := new(ERC20TokenStakingManagerDelegatorRewardRecipientChanged) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRewardRecipientChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitializedIterator struct { + Event *ERC20TokenStakingManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerInitialized represents a Initialized event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ERC20TokenStakingManagerInitializedIterator, error) { + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerInitializedIterator{contract: _ERC20TokenStakingManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseInitialized(log types.Log) (*ERC20TokenStakingManagerInitialized, error) { + event := new(ERC20TokenStakingManagerInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerInitiatedDelegatorRegistrationIterator is returned from FilterInitiatedDelegatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedDelegatorRegistration events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitiatedDelegatorRegistrationIterator struct { + Event *ERC20TokenStakingManagerInitiatedDelegatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerInitiatedDelegatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitiatedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitiatedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerInitiatedDelegatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerInitiatedDelegatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerInitiatedDelegatorRegistration represents a InitiatedDelegatorRegistration event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitiatedDelegatorRegistration struct { + DelegationID [32]byte + ValidationID [32]byte + DelegatorAddress common.Address + Nonce uint64 + ValidatorWeight uint64 + DelegatorWeight uint64 + SetWeightMessageID [32]byte + RewardRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedDelegatorRegistration is a free log retrieval operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterInitiatedDelegatorRegistration(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (*ERC20TokenStakingManagerInitiatedDelegatorRegistrationIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "InitiatedDelegatorRegistration", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerInitiatedDelegatorRegistrationIterator{contract: _ERC20TokenStakingManager.contract, event: "InitiatedDelegatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedDelegatorRegistration is a free log subscription operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchInitiatedDelegatorRegistration(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerInitiatedDelegatorRegistration, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "InitiatedDelegatorRegistration", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerInitiatedDelegatorRegistration) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRegistration", 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 +} + +// ParseInitiatedDelegatorRegistration is a log parse operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseInitiatedDelegatorRegistration(log types.Log) (*ERC20TokenStakingManagerInitiatedDelegatorRegistration, error) { + event := new(ERC20TokenStakingManagerInitiatedDelegatorRegistration) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerInitiatedDelegatorRemovalIterator is returned from FilterInitiatedDelegatorRemoval and is used to iterate over the raw logs and unpacked data for InitiatedDelegatorRemoval events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitiatedDelegatorRemovalIterator struct { + Event *ERC20TokenStakingManagerInitiatedDelegatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerInitiatedDelegatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitiatedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitiatedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerInitiatedDelegatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerInitiatedDelegatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerInitiatedDelegatorRemoval represents a InitiatedDelegatorRemoval event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitiatedDelegatorRemoval struct { + DelegationID [32]byte + ValidationID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedDelegatorRemoval is a free log retrieval operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterInitiatedDelegatorRemoval(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*ERC20TokenStakingManagerInitiatedDelegatorRemovalIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "InitiatedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerInitiatedDelegatorRemovalIterator{contract: _ERC20TokenStakingManager.contract, event: "InitiatedDelegatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchInitiatedDelegatorRemoval is a free log subscription operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchInitiatedDelegatorRemoval(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerInitiatedDelegatorRemoval, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "InitiatedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerInitiatedDelegatorRemoval) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRemoval", 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 +} + +// ParseInitiatedDelegatorRemoval is a log parse operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseInitiatedDelegatorRemoval(log types.Log) (*ERC20TokenStakingManagerInitiatedDelegatorRemoval, error) { + event := new(ERC20TokenStakingManagerInitiatedDelegatorRemoval) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerInitiatedStakingValidatorRegistrationIterator is returned from FilterInitiatedStakingValidatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedStakingValidatorRegistration events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitiatedStakingValidatorRegistrationIterator struct { + Event *ERC20TokenStakingManagerInitiatedStakingValidatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerInitiatedStakingValidatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitiatedStakingValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitiatedStakingValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerInitiatedStakingValidatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerInitiatedStakingValidatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerInitiatedStakingValidatorRegistration represents a InitiatedStakingValidatorRegistration event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitiatedStakingValidatorRegistration struct { + ValidationID [32]byte + Owner common.Address + DelegationFeeBips uint16 + MinStakeDuration uint64 + RewardRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedStakingValidatorRegistration is a free log retrieval operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterInitiatedStakingValidatorRegistration(opts *bind.FilterOpts, validationID [][32]byte, owner []common.Address) (*ERC20TokenStakingManagerInitiatedStakingValidatorRegistrationIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "InitiatedStakingValidatorRegistration", validationIDRule, ownerRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerInitiatedStakingValidatorRegistrationIterator{contract: _ERC20TokenStakingManager.contract, event: "InitiatedStakingValidatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedStakingValidatorRegistration is a free log subscription operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchInitiatedStakingValidatorRegistration(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerInitiatedStakingValidatorRegistration, validationID [][32]byte, owner []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "InitiatedStakingValidatorRegistration", validationIDRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerInitiatedStakingValidatorRegistration) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitiatedStakingValidatorRegistration", 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 +} + +// ParseInitiatedStakingValidatorRegistration is a log parse operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseInitiatedStakingValidatorRegistration(log types.Log) (*ERC20TokenStakingManagerInitiatedStakingValidatorRegistration, error) { + event := new(ERC20TokenStakingManagerInitiatedStakingValidatorRegistration) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitiatedStakingValidatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerUptimeUpdatedIterator is returned from FilterUptimeUpdated and is used to iterate over the raw logs and unpacked data for UptimeUpdated events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerUptimeUpdatedIterator struct { + Event *ERC20TokenStakingManagerUptimeUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerUptimeUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerUptimeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerUptimeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerUptimeUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerUptimeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerUptimeUpdated represents a UptimeUpdated event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerUptimeUpdated struct { + ValidationID [32]byte + Uptime uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUptimeUpdated is a free log retrieval operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterUptimeUpdated(opts *bind.FilterOpts, validationID [][32]byte) (*ERC20TokenStakingManagerUptimeUpdatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "UptimeUpdated", validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerUptimeUpdatedIterator{contract: _ERC20TokenStakingManager.contract, event: "UptimeUpdated", logs: logs, sub: sub}, nil +} + +// WatchUptimeUpdated is a free log subscription operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchUptimeUpdated(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerUptimeUpdated, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "UptimeUpdated", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerUptimeUpdated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "UptimeUpdated", 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 +} + +// ParseUptimeUpdated is a log parse operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseUptimeUpdated(log types.Log) (*ERC20TokenStakingManagerUptimeUpdated, error) { + event := new(ERC20TokenStakingManagerUptimeUpdated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "UptimeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidatorRewardClaimedIterator is returned from FilterValidatorRewardClaimed and is used to iterate over the raw logs and unpacked data for ValidatorRewardClaimed events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRewardClaimedIterator struct { + Event *ERC20TokenStakingManagerValidatorRewardClaimed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidatorRewardClaimedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidatorRewardClaimedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidatorRewardClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidatorRewardClaimed represents a ValidatorRewardClaimed event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRewardClaimed struct { + ValidationID [32]byte + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRewardClaimed is a free log retrieval operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidatorRewardClaimed(opts *bind.FilterOpts, validationID [][32]byte, recipient []common.Address) (*ERC20TokenStakingManagerValidatorRewardClaimedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidatorRewardClaimed", validationIDRule, recipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidatorRewardClaimedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidatorRewardClaimed", logs: logs, sub: sub}, nil +} + +// WatchValidatorRewardClaimed is a free log subscription operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidatorRewardClaimed(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidatorRewardClaimed, validationID [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidatorRewardClaimed", validationIDRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidatorRewardClaimed) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRewardClaimed", 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 +} + +// ParseValidatorRewardClaimed is a log parse operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidatorRewardClaimed(log types.Log) (*ERC20TokenStakingManagerValidatorRewardClaimed, error) { + event := new(ERC20TokenStakingManagerValidatorRewardClaimed) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRewardClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidatorRewardRecipientChangedIterator is returned from FilterValidatorRewardRecipientChanged and is used to iterate over the raw logs and unpacked data for ValidatorRewardRecipientChanged events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRewardRecipientChangedIterator struct { + Event *ERC20TokenStakingManagerValidatorRewardRecipientChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidatorRewardRecipientChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidatorRewardRecipientChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidatorRewardRecipientChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidatorRewardRecipientChanged represents a ValidatorRewardRecipientChanged event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRewardRecipientChanged struct { + ValidationID [32]byte + Recipient common.Address + OldRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRewardRecipientChanged is a free log retrieval operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidatorRewardRecipientChanged(opts *bind.FilterOpts, validationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (*ERC20TokenStakingManagerValidatorRewardRecipientChangedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidatorRewardRecipientChanged", validationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidatorRewardRecipientChangedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidatorRewardRecipientChanged", logs: logs, sub: sub}, nil +} + +// WatchValidatorRewardRecipientChanged is a free log subscription operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidatorRewardRecipientChanged(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidatorRewardRecipientChanged, validationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidatorRewardRecipientChanged", validationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidatorRewardRecipientChanged) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRewardRecipientChanged", 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 +} + +// ParseValidatorRewardRecipientChanged is a log parse operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidatorRewardRecipientChanged(log types.Log) (*ERC20TokenStakingManagerValidatorRewardRecipientChanged, error) { + event := new(ERC20TokenStakingManagerValidatorRewardRecipientChanged) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRewardRecipientChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorMessagesMetaData contains all meta data concerning the ValidatorMessages contract. +var ValidatorMessagesMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"InvalidBLSPublicKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"InvalidCodecID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"actual\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageType\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"validatorManagerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structInitialValidator[]\",\"name\":\"initialValidators\",\"type\":\"tuple[]\"}],\"internalType\":\"structConversionData\",\"name\":\"conversionData\",\"type\":\"tuple\"}],\"name\":\"packConversionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"}],\"name\":\"packL1ValidatorRegistrationMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"packL1ValidatorWeightMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structValidatorMessages.ValidationPeriod\",\"name\":\"validationPeriod\",\"type\":\"tuple\"}],\"name\":\"packRegisterL1ValidatorMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"conversionID\",\"type\":\"bytes32\"}],\"name\":\"packSubnetToL1ConversionMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"uptime\",\"type\":\"uint64\"}],\"name\":\"packValidationUptimeMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackL1ValidatorRegistrationMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackL1ValidatorWeightMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackRegisterL1ValidatorMessage\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structValidatorMessages.ValidationPeriod\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackSubnetToL1ConversionMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackValidationUptimeMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x61217b610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100b1575f3560e01c8063854a893f11610079578063854a893f146101b257806387418b8e1461020f5780639b83546514610222578063a699c13514610242578063e1d68f3014610255578063eb97ce5114610268575f80fd5b8063021de88f146100b5578063088c2463146100e25780634d8478841461011257806350782b0f146101335780637f7c427a1461016b575b5f80fd5b6100c86100c33660046118a9565b610289565b604080519283529015156020830152015b60405180910390f35b6100f56100f03660046118a9565b61044a565b604080519283526001600160401b039091166020830152016100d9565b6101256101203660046118a9565b61063b565b6040519081526020016100d9565b6101466101413660046118a9565b6107c8565b604080519384526001600160401b0392831660208501529116908201526060016100d9565b6101a56101793660046118e2565b604080515f60208201819052602282015260268082019390935281518082039093018352604601905290565b6040516100d99190611946565b6101a56101c036600461197a565b604080515f6020820152600360e01b602282015260268101949094526001600160c01b031960c093841b811660468601529190921b16604e830152805180830360360181526056909201905290565b6101a561021d3660046119eb565b610a1e565b6102356102303660046118a9565b610b60565b6040516100d99190611bb4565b6101a5610250366004611c6b565b6114ab565b6101a5610263366004611c9d565b6114ef565b61027b610276366004611d80565b611525565b6040516100d9929190611e7c565b5f8082516027146102c457825160405163cc92daa160e01b815263ffffffff9091166004820152602760248201526044015b60405180910390fd5b5f805b6002811015610313576102db816001611ea8565b6102e6906008611ebb565b61ffff168582815181106102fc576102fc611ed2565b016020015160f81c901b91909117906001016102c7565b5061ffff81161561033d5760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561039857610354816003611ea8565b61035f906008611ebb565b63ffffffff1686610371836002611ee6565b8151811061038157610381611ed2565b016020015160f81c901b9190911790600101610340565b5063ffffffff81166002146103c057604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015610415576103d781601f611ea8565b6103e2906008611ebb565b876103ee836006611ee6565b815181106103fe576103fe611ed2565b016020015160f81c901b91909117906001016103c3565b505f8660268151811061042a5761042a611ed2565b016020015191976001600160f81b03199092161515965090945050505050565b5f808251602e1461048057825160405163cc92daa160e01b815263ffffffff9091166004820152602e60248201526044016102bb565b5f805b60028110156104cf57610497816001611ea8565b6104a2906008611ebb565b61ffff168582815181106104b8576104b8611ed2565b016020015160f81c901b9190911790600101610483565b5061ffff8116156104f95760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561055457610510816003611ea8565b61051b906008611ebb565b63ffffffff168661052d836002611ee6565b8151811061053d5761053d611ed2565b016020015160f81c901b91909117906001016104fc565b5063ffffffff81161561057a57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156105cf5761059181601f611ea8565b61059c906008611ebb565b876105a8836006611ee6565b815181106105b8576105b8611ed2565b016020015160f81c901b919091179060010161057d565b505f805b600881101561062e576105e7816007611ea8565b6105f2906008611ebb565b6001600160401b031688610607836026611ee6565b8151811061061757610617611ed2565b016020015160f81c901b91909117906001016105d3565b5090969095509350505050565b5f815160261461067057815160405163cc92daa160e01b815263ffffffff9091166004820152602660248201526044016102bb565b5f805b60028110156106bf57610687816001611ea8565b610692906008611ebb565b61ffff168482815181106106a8576106a8611ed2565b016020015160f81c901b9190911790600101610673565b5061ffff8116156106e95760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561074457610700816003611ea8565b61070b906008611ebb565b63ffffffff168561071d836002611ee6565b8151811061072d5761072d611ed2565b016020015160f81c901b91909117906001016106ec565b5063ffffffff81161561076a57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156107bf5761078181601f611ea8565b61078c906008611ebb565b86610798836006611ee6565b815181106107a8576107a8611ed2565b016020015160f81c901b919091179060010161076d565b50949350505050565b5f805f83516036146107ff57835160405163cc92daa160e01b815263ffffffff9091166004820152603660248201526044016102bb565b5f805b600281101561084e57610816816001611ea8565b610821906008611ebb565b61ffff1686828151811061083757610837611ed2565b016020015160f81c901b9190911790600101610802565b5061ffff8116156108785760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b60048110156108d35761088f816003611ea8565b61089a906008611ebb565b63ffffffff16876108ac836002611ee6565b815181106108bc576108bc611ed2565b016020015160f81c901b919091179060010161087b565b5063ffffffff81166003146108fb57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156109505761091281601f611ea8565b61091d906008611ebb565b88610929836006611ee6565b8151811061093957610939611ed2565b016020015160f81c901b91909117906001016108fe565b505f805b60088110156109af57610968816007611ea8565b610973906008611ebb565b6001600160401b031689610988836026611ee6565b8151811061099857610998611ed2565b016020015160f81c901b9190911790600101610954565b505f805b6008811015610a0e576109c7816007611ea8565b6109d2906008611ebb565b6001600160401b03168a6109e783602e611ee6565b815181106109f7576109f7611ed2565b016020015160f81c901b91909117906001016109b3565b5091989097509095509350505050565b80516020808301516040808501516060868101515192515f95810186905260228101969096526042860193909352600560e21b60628601526bffffffffffffffffffffffff1990831b16606685015260e01b6001600160e01b031916607a84015291607e0160405160208183030381529060405290505f5b836060015151811015610b59578184606001518281518110610aba57610aba611ed2565b60200260200101515f01515185606001518381518110610adc57610adc611ed2565b60200260200101515f015186606001518481518110610afd57610afd611ed2565b60200260200101516020015187606001518581518110610b1f57610b1f611ed2565b602002602001015160400151604051602001610b3f959493929190611ef9565b60408051601f198184030181529190529150600101610a96565b5092915050565b610b68611712565b5f610b71611712565b5f805b6002811015610bcf57610b88816001611ea8565b610b93906008611ebb565b61ffff1686610ba863ffffffff871684611ee6565b81518110610bb857610bb8611ed2565b016020015160f81c901b9190911790600101610b74565b5061ffff811615610bf95760405163407b587360e01b815261ffff821660048201526024016102bb565b610c04600284611f72565b9250505f805b6004811015610c6957610c1e816003611ea8565b610c29906008611ebb565b63ffffffff16868563ffffffff1683610c429190611ee6565b81518110610c5257610c52611ed2565b016020015160f81c901b9190911790600101610c0a565b5063ffffffff8116600114610c9157604051635b60892f60e01b815260040160405180910390fd5b610c9c600484611f72565b9250505f805b6020811015610cf957610cb681601f611ea8565b610cc1906008611ebb565b86610cd263ffffffff871684611ee6565b81518110610ce257610ce2611ed2565b016020015160f81c901b9190911790600101610ca2565b50808252610d08602084611f72565b9250505f805b6004811015610d6d57610d22816003611ea8565b610d2d906008611ebb565b63ffffffff16868563ffffffff1683610d469190611ee6565b81518110610d5657610d56611ed2565b016020015160f81c901b9190911790600101610d0e565b50610d79600484611f72565b92505f8163ffffffff166001600160401b03811115610d9a57610d9a61176c565b6040519080825280601f01601f191660200182016040528015610dc4576020820181803683370190505b5090505f5b8263ffffffff16811015610e335786610de863ffffffff871683611ee6565b81518110610df857610df8611ed2565b602001015160f81c60f81b828281518110610e1557610e15611ed2565b60200101906001600160f81b03191690815f1a905350600101610dc9565b5060208301819052610e458285611f72565b604080516030808252606082019092529195505f92506020820181803683370190505090505f5b6030811015610ed15786610e8663ffffffff871683611ee6565b81518110610e9657610e96611ed2565b602001015160f81c60f81b828281518110610eb357610eb3611ed2565b60200101906001600160f81b03191690815f1a905350600101610e6c565b5060408301819052610ee4603085611f72565b9350505f805b6008811015610f4a57610efe816007611ea8565b610f09906008611ebb565b6001600160401b031687610f2363ffffffff881684611ee6565b81518110610f3357610f33611ed2565b016020015160f81c901b9190911790600101610eea565b506001600160401b0381166060840152610f65600885611f72565b9350505f805f5b6004811015610fcb57610f80816003611ea8565b610f8b906008611ebb565b63ffffffff16888763ffffffff1683610fa49190611ee6565b81518110610fb457610fb4611ed2565b016020015160f81c901b9190911790600101610f6c565b50610fd7600486611f72565b94505f5b600481101561103a57610fef816003611ea8565b610ffa906008611ebb565b63ffffffff16888763ffffffff16836110139190611ee6565b8151811061102357611023611ed2565b016020015160f81c901b9290921791600101610fdb565b50611046600486611f72565b94505f8263ffffffff166001600160401b038111156110675761106761176c565b604051908082528060200260200182016040528015611090578160200160208202803683370190505b5090505f5b8363ffffffff16811015611178576040805160148082528183019092525f916020820181803683370190505090505f5b601481101561112a578a6110df63ffffffff8b1683611ee6565b815181106110ef576110ef611ed2565b602001015160f81c60f81b82828151811061110c5761110c611ed2565b60200101906001600160f81b03191690815f1a9053506001016110c5565b505f601482015190508084848151811061114657611146611ed2565b6001600160a01b039092166020928302919091019091015261116960148a611f72565b98505050806001019050611095565b506040805180820190915263ffffffff9092168252602082015260808401525f80805b60048110156111fa576111af816003611ea8565b6111ba906008611ebb565b63ffffffff16898863ffffffff16836111d39190611ee6565b815181106111e3576111e3611ed2565b016020015160f81c901b919091179060010161119b565b50611206600487611f72565b95505f5b60048110156112695761121e816003611ea8565b611229906008611ebb565b63ffffffff16898863ffffffff16836112429190611ee6565b8151811061125257611252611ed2565b016020015160f81c901b929092179160010161120a565b50611275600487611f72565b95505f8263ffffffff166001600160401b038111156112965761129661176c565b6040519080825280602002602001820160405280156112bf578160200160208202803683370190505b5090505f5b8363ffffffff168110156113a7576040805160148082528183019092525f916020820181803683370190505090505f5b6014811015611359578b61130e63ffffffff8c1683611ee6565b8151811061131e5761131e611ed2565b602001015160f81c60f81b82828151811061133b5761133b611ed2565b60200101906001600160f81b03191690815f1a9053506001016112f4565b505f601482015190508084848151811061137557611375611ed2565b6001600160a01b039092166020928302919091019091015261139860148b611f72565b995050508060010190506112c4565b506040805180820190915263ffffffff9092168252602082015260a08501525f6113d18284611f72565b6113dc906014611f8f565b6113e785607a611f72565b6113f19190611f72565b90508063ffffffff1688511461142d57875160405163cc92daa160e01b815263ffffffff918216600482015290821660248201526044016102bb565b5f805b600881101561149057611444816007611ea8565b61144f906008611ebb565b6001600160401b03168a61146963ffffffff8b1684611ee6565b8151811061147957611479611ed2565b016020015160f81c901b9190911790600101611430565b506001600160401b031660c086015250929695505050505050565b6040515f6020820152600160e11b60228201526026810183905281151560f81b60468201526060906047015b60405160208183030381529060405290505b92915050565b6040515f602082018190526022820152602681018390526001600160c01b031960c083901b166046820152606090604e016114d7565b5f606082604001515160301461154e5760405163180ffa0d60e01b815260040160405180910390fd5b82516020808501518051604080880151606089015160808a01518051908701515193515f9861158f988a986001989297929690959094909390929101611fb7565b60405160208183030381529060405290505f5b84608001516020015151811015611601578185608001516020015182815181106115ce576115ce611ed2565b60200260200101516040516020016115e7929190612071565b60408051601f1981840301815291905291506001016115a2565b5060a08401518051602091820151516040516116219385939291016120a7565b60405160208183030381529060405290505f5b8460a00151602001515181101561169357818560a0015160200151828151811061166057611660611ed2565b6020026020010151604051602001611679929190612071565b60408051601f198184030181529190529150600101611634565b5060c08401516040516116aa9183916020016120e2565b60405160208183030381529060405290506002816040516116cb9190612113565b602060405180830381855afa1580156116e6573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611709919061212e565b94909350915050565b6040805160e0810182525f808252606060208084018290528385018290528184018390528451808601865283815280820183905260808501528451808601909552918452908301529060a082019081525f60209091015290565b634e487b7160e01b5f52604160045260245ffd5b604051608081016001600160401b03811182821017156117a2576117a261176c565b60405290565b604051606081016001600160401b03811182821017156117a2576117a261176c565b604080519081016001600160401b03811182821017156117a2576117a261176c565b60405160e081016001600160401b03811182821017156117a2576117a261176c565b604051601f8201601f191681016001600160401b03811182821017156118365761183661176c565b604052919050565b5f82601f83011261184d575f80fd5b81356001600160401b038111156118665761186661176c565b611879601f8201601f191660200161180e565b81815284602083860101111561188d575f80fd5b816020850160208301375f918101602001919091529392505050565b5f602082840312156118b9575f80fd5b81356001600160401b038111156118ce575f80fd5b6118da8482850161183e565b949350505050565b5f602082840312156118f2575f80fd5b5035919050565b5f5b838110156119135781810151838201526020016118fb565b50505f910152565b5f81518084526119328160208601602086016118f9565b601f01601f19169290920160200192915050565b602081525f611958602083018461191b565b9392505050565b80356001600160401b0381168114611975575f80fd5b919050565b5f805f6060848603121561198c575f80fd5b8335925061199c6020850161195f565b91506119aa6040850161195f565b90509250925092565b80356001600160a01b0381168114611975575f80fd5b5f6001600160401b038211156119e1576119e161176c565b5060051b60200190565b5f60208083850312156119fc575f80fd5b82356001600160401b0380821115611a12575f80fd5b9084019060808287031215611a25575f80fd5b611a2d611780565b823581528383013584820152611a45604084016119b3565b604082015260608084013583811115611a5c575f80fd5b80850194505087601f850112611a70575f80fd5b8335611a83611a7e826119c9565b61180e565b81815260059190911b8501860190868101908a831115611aa1575f80fd5b8787015b83811015611b3a57803587811115611abb575f80fd5b8801808d03601f1901861315611acf575f80fd5b611ad76117a8565b8a82013589811115611ae7575f80fd5b611af58f8d8386010161183e565b825250604082013589811115611b09575f80fd5b611b178f8d8386010161183e565b8c83015250611b2787830161195f565b6040820152845250918801918801611aa5565b506060850152509198975050505050505050565b5f6040830163ffffffff8351168452602080840151604060208701528281518085526060880191506020830194505f92505b80831015611ba95784516001600160a01b03168252938301936001929092019190830190611b80565b509695505050505050565b60208152815160208201525f602083015160e06040840152611bda61010084018261191b565b90506040840151601f1980858403016060860152611bf8838361191b565b92506001600160401b03606087015116608086015260808601519150808584030160a0860152611c288383611b4e565b925060a08601519150808584030160c086015250611c468282611b4e565b91505060c0840151611c6360e08501826001600160401b03169052565b509392505050565b5f8060408385031215611c7c575f80fd5b8235915060208301358015158114611c92575f80fd5b809150509250929050565b5f8060408385031215611cae575f80fd5b82359150611cbe6020840161195f565b90509250929050565b5f60408284031215611cd7575f80fd5b611cdf6117ca565b9050813563ffffffff81168114611cf4575f80fd5b81526020828101356001600160401b03811115611d0f575f80fd5b8301601f81018513611d1f575f80fd5b8035611d2d611a7e826119c9565b81815260059190911b82018301908381019087831115611d4b575f80fd5b928401925b82841015611d7057611d61846119b3565b82529284019290840190611d50565b8085870152505050505092915050565b5f60208284031215611d90575f80fd5b81356001600160401b0380821115611da6575f80fd5b9083019060e08286031215611db9575f80fd5b611dc16117ec565b82358152602083013582811115611dd6575f80fd5b611de28782860161183e565b602083015250604083013582811115611df9575f80fd5b611e058782860161183e565b604083015250611e176060840161195f565b6060820152608083013582811115611e2d575f80fd5b611e3987828601611cc7565b60808301525060a083013582811115611e50575f80fd5b611e5c87828601611cc7565b60a083015250611e6e60c0840161195f565b60c082015295945050505050565b828152604060208201525f6118da604083018461191b565b634e487b7160e01b5f52601160045260245ffd5b818103818111156114e9576114e9611e94565b80820281158282048414176114e9576114e9611e94565b634e487b7160e01b5f52603260045260245ffd5b808201808211156114e9576114e9611e94565b5f8651611f0a818460208b016118f9565b60e087901b6001600160e01b0319169083019081528551611f32816004840160208a016118f9565b8551910190611f488160048401602089016118f9565b60c09490941b6001600160c01b031916600491909401908101939093525050600c01949350505050565b63ffffffff818116838216019080821115610b5957610b59611e94565b63ffffffff818116838216028082169190828114611faf57611faf611e94565b505092915050565b61ffff60f01b8a60f01b1681525f63ffffffff60e01b808b60e01b166002840152896006840152808960e01b166026840152508651611ffd81602a850160208b016118f9565b86519083019061201481602a840160208b016118f9565b60c087901b6001600160c01b031916602a9290910191820152612046603282018660e01b6001600160e01b0319169052565b61205f603682018560e01b6001600160e01b0319169052565b603a019b9a5050505050505050505050565b5f83516120828184602088016118f9565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b5f84516120b88184602089016118f9565b6001600160e01b031960e095861b8116919093019081529290931b16600482015260080192915050565b5f83516120f38184602088016118f9565b60c09390931b6001600160c01b0319169190920190815260080192915050565b5f82516121248184602087016118f9565b9190910192915050565b5f6020828403121561213e575f80fd5b505191905056fea26469706673582212204c79a1f4a6f5c66db9481c372405f40b1b5d511151053a9518bb9ce8f1032e4164736f6c63430008190033", +} + +// ValidatorMessagesABI is the input ABI used to generate the binding from. +// Deprecated: Use ValidatorMessagesMetaData.ABI instead. +var ValidatorMessagesABI = ValidatorMessagesMetaData.ABI + +// ValidatorMessagesBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ValidatorMessagesMetaData.Bin instead. +var ValidatorMessagesBin = ValidatorMessagesMetaData.Bin + +// DeployValidatorMessages deploys a new Ethereum contract, binding an instance of ValidatorMessages to it. +func DeployValidatorMessages(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ValidatorMessages, error) { + parsed, err := ValidatorMessagesMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ValidatorMessagesBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ValidatorMessages{ValidatorMessagesCaller: ValidatorMessagesCaller{contract: contract}, ValidatorMessagesTransactor: ValidatorMessagesTransactor{contract: contract}, ValidatorMessagesFilterer: ValidatorMessagesFilterer{contract: contract}}, nil +} + +// ValidatorMessages is an auto generated Go binding around an Ethereum contract. +type ValidatorMessages struct { + ValidatorMessagesCaller // Read-only binding to the contract + ValidatorMessagesTransactor // Write-only binding to the contract + ValidatorMessagesFilterer // Log filterer for contract events +} + +// ValidatorMessagesCaller is an auto generated read-only Go binding around an Ethereum contract. +type ValidatorMessagesCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ValidatorMessagesTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ValidatorMessagesFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ValidatorMessagesSession struct { + Contract *ValidatorMessages // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorMessagesCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ValidatorMessagesCallerSession struct { + Contract *ValidatorMessagesCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ValidatorMessagesTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ValidatorMessagesTransactorSession struct { + Contract *ValidatorMessagesTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorMessagesRaw is an auto generated low-level Go binding around an Ethereum contract. +type ValidatorMessagesRaw struct { + Contract *ValidatorMessages // Generic contract binding to access the raw methods on +} + +// ValidatorMessagesCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ValidatorMessagesCallerRaw struct { + Contract *ValidatorMessagesCaller // Generic read-only contract binding to access the raw methods on +} + +// ValidatorMessagesTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ValidatorMessagesTransactorRaw struct { + Contract *ValidatorMessagesTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewValidatorMessages creates a new instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessages(address common.Address, backend bind.ContractBackend) (*ValidatorMessages, error) { + contract, err := bindValidatorMessages(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ValidatorMessages{ValidatorMessagesCaller: ValidatorMessagesCaller{contract: contract}, ValidatorMessagesTransactor: ValidatorMessagesTransactor{contract: contract}, ValidatorMessagesFilterer: ValidatorMessagesFilterer{contract: contract}}, nil +} + +// NewValidatorMessagesCaller creates a new read-only instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesCaller(address common.Address, caller bind.ContractCaller) (*ValidatorMessagesCaller, error) { + contract, err := bindValidatorMessages(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ValidatorMessagesCaller{contract: contract}, nil +} + +// NewValidatorMessagesTransactor creates a new write-only instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorMessagesTransactor, error) { + contract, err := bindValidatorMessages(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ValidatorMessagesTransactor{contract: contract}, nil +} + +// NewValidatorMessagesFilterer creates a new log filterer instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorMessagesFilterer, error) { + contract, err := bindValidatorMessages(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ValidatorMessagesFilterer{contract: contract}, nil +} + +// bindValidatorMessages binds a generic wrapper to an already deployed contract. +func bindValidatorMessages(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ValidatorMessagesMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorMessages *ValidatorMessagesRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorMessages.Contract.ValidatorMessagesCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorMessages *ValidatorMessagesRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorMessages.Contract.ValidatorMessagesTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorMessages *ValidatorMessagesRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorMessages.Contract.ValidatorMessagesTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorMessages *ValidatorMessagesCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorMessages.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorMessages *ValidatorMessagesTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorMessages.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorMessages *ValidatorMessagesTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorMessages.Contract.contract.Transact(opts, method, params...) +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackConversionData(opts *bind.CallOpts, conversionData ConversionData) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packConversionData", conversionData) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackConversionData(conversionData ConversionData) ([]byte, error) { + return _ValidatorMessages.Contract.PackConversionData(&_ValidatorMessages.CallOpts, conversionData) +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackConversionData(conversionData ConversionData) ([]byte, error) { + return _ValidatorMessages.Contract.PackConversionData(&_ValidatorMessages.CallOpts, conversionData) +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackL1ValidatorRegistrationMessage(opts *bind.CallOpts, validationID [32]byte, registered bool) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packL1ValidatorRegistrationMessage", validationID, registered) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackL1ValidatorRegistrationMessage(validationID [32]byte, registered bool) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, validationID, registered) +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackL1ValidatorRegistrationMessage(validationID [32]byte, registered bool) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, validationID, registered) +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackL1ValidatorWeightMessage(opts *bind.CallOpts, validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packL1ValidatorWeightMessage", validationID, nonce, weight) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackL1ValidatorWeightMessage(validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, validationID, nonce, weight) +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackL1ValidatorWeightMessage(validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, validationID, nonce, weight) +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackRegisterL1ValidatorMessage(opts *bind.CallOpts, validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packRegisterL1ValidatorMessage", validationPeriod) + + if err != nil { + return *new([32]byte), *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte) + + return out0, out1, err + +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackRegisterL1ValidatorMessage(validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + return _ValidatorMessages.Contract.PackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, validationPeriod) +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackRegisterL1ValidatorMessage(validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + return _ValidatorMessages.Contract.PackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, validationPeriod) +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackSubnetToL1ConversionMessage(opts *bind.CallOpts, conversionID [32]byte) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packSubnetToL1ConversionMessage", conversionID) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackSubnetToL1ConversionMessage(conversionID [32]byte) ([]byte, error) { + return _ValidatorMessages.Contract.PackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, conversionID) +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackSubnetToL1ConversionMessage(conversionID [32]byte) ([]byte, error) { + return _ValidatorMessages.Contract.PackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, conversionID) +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackValidationUptimeMessage(opts *bind.CallOpts, validationID [32]byte, uptime uint64) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packValidationUptimeMessage", validationID, uptime) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackValidationUptimeMessage(validationID [32]byte, uptime uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackValidationUptimeMessage(&_ValidatorMessages.CallOpts, validationID, uptime) +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackValidationUptimeMessage(validationID [32]byte, uptime uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackValidationUptimeMessage(&_ValidatorMessages.CallOpts, validationID, uptime) +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackL1ValidatorRegistrationMessage(opts *bind.CallOpts, input []byte) ([32]byte, bool, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackL1ValidatorRegistrationMessage", input) + + if err != nil { + return *new([32]byte), *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(bool)).(*bool) + + return out0, out1, err + +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackL1ValidatorRegistrationMessage(input []byte) ([32]byte, bool, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackL1ValidatorRegistrationMessage(input []byte) ([32]byte, bool, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackL1ValidatorWeightMessage(opts *bind.CallOpts, input []byte) ([32]byte, uint64, uint64, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackL1ValidatorWeightMessage", input) + + if err != nil { + return *new([32]byte), *new(uint64), *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(uint64)).(*uint64) + out2 := *abi.ConvertType(out[2], new(uint64)).(*uint64) + + return out0, out1, out2, err + +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackL1ValidatorWeightMessage(input []byte) ([32]byte, uint64, uint64, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackL1ValidatorWeightMessage(input []byte) ([32]byte, uint64, uint64, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackRegisterL1ValidatorMessage(opts *bind.CallOpts, input []byte) (ValidatorMessagesValidationPeriod, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackRegisterL1ValidatorMessage", input) + + if err != nil { + return *new(ValidatorMessagesValidationPeriod), err + } + + out0 := *abi.ConvertType(out[0], new(ValidatorMessagesValidationPeriod)).(*ValidatorMessagesValidationPeriod) + + return out0, err + +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackRegisterL1ValidatorMessage(input []byte) (ValidatorMessagesValidationPeriod, error) { + return _ValidatorMessages.Contract.UnpackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackRegisterL1ValidatorMessage(input []byte) (ValidatorMessagesValidationPeriod, error) { + return _ValidatorMessages.Contract.UnpackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackSubnetToL1ConversionMessage(opts *bind.CallOpts, input []byte) ([32]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackSubnetToL1ConversionMessage", input) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackSubnetToL1ConversionMessage(input []byte) ([32]byte, error) { + return _ValidatorMessages.Contract.UnpackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackSubnetToL1ConversionMessage(input []byte) ([32]byte, error) { + return _ValidatorMessages.Contract.UnpackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackValidationUptimeMessage(opts *bind.CallOpts, input []byte) ([32]byte, uint64, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackValidationUptimeMessage", input) + + if err != nil { + return *new([32]byte), *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return out0, out1, err + +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackValidationUptimeMessage(input []byte) ([32]byte, uint64, error) { + return _ValidatorMessages.Contract.UnpackValidationUptimeMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackValidationUptimeMessage(input []byte) ([32]byte, uint64, error) { + return _ValidatorMessages.Contract.UnpackValidationUptimeMessage(&_ValidatorMessages.CallOpts, input) +} diff --git a/abi-bindings/go/validator-manager/ExampleRewardCalculator/ExampleRewardCalculator.go b/abi-bindings/go/validator-manager/ExampleRewardCalculator/ExampleRewardCalculator.go new file mode 100644 index 000000000..9b13ac6e0 --- /dev/null +++ b/abi-bindings/go/validator-manager/ExampleRewardCalculator/ExampleRewardCalculator.go @@ -0,0 +1,358 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package examplerewardcalculator + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ExampleRewardCalculatorMetaData contains all meta data concerning the ExampleRewardCalculator contract. +var ExampleRewardCalculatorMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"rewardBasisPoints_\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BIPS_CONVERSION_FACTOR\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SECONDS_IN_YEAR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UPTIME_REWARDS_THRESHOLD_PERCENTAGE\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"stakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"validatorStartTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"stakingStartTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"stakingEndTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"uptimeSeconds\",\"type\":\"uint64\"}],\"name\":\"calculateReward\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardBasisPoints\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60a0604052348015600e575f80fd5b50604051610393380380610393833981016040819052602b91603b565b6001600160401b03166080526066565b5f60208284031215604a575f80fd5b81516001600160401b0381168114605f575f80fd5b9392505050565b60805161030f6100845f395f818160c50152610161015261030f5ff3fe608060405234801561000f575f80fd5b5060043610610055575f3560e01c80634f22429f146100595780635dcc93911461007f578063a9778a7a1461008a578063afba878a146100a6578063bb65b242146100c0575b5f80fd5b61006c6100673660046101db565b610100565b6040519081526020015b60405180910390f35b61006c6301e1338081565b61009361271081565b60405161ffff9091168152602001610076565b6100ae605081565b60405160ff9091168152602001610076565b6100e77f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff9091168152602001610076565b5f605061010d8685610249565b6101179190610271565b67ffffffffffffffff1661012c836064610271565b67ffffffffffffffff16101561014357505f6101b6565b6127106301e133806101558686610249565b67ffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1689610195919061029d565b61019f919061029d565b6101a991906102ba565b6101b391906102ba565b90505b95945050505050565b803567ffffffffffffffff811681146101d6575f80fd5b919050565b5f805f805f60a086880312156101ef575f80fd5b853594506101ff602087016101bf565b935061020d604087016101bf565b925061021b606087016101bf565b9150610229608087016101bf565b90509295509295909350565b634e487b7160e01b5f52601160045260245ffd5b67ffffffffffffffff82811682821603908082111561026a5761026a610235565b5092915050565b67ffffffffffffffff81811683821602808216919082811461029557610295610235565b505092915050565b80820281158282048414176102b4576102b4610235565b92915050565b5f826102d457634e487b7160e01b5f52601260045260245ffd5b50049056fea2646970667358221220398c683c23e05f5359e16f15076da8238fc8b9df343fd4d6a248c53a83e3cf3064736f6c63430008190033", +} + +// ExampleRewardCalculatorABI is the input ABI used to generate the binding from. +// Deprecated: Use ExampleRewardCalculatorMetaData.ABI instead. +var ExampleRewardCalculatorABI = ExampleRewardCalculatorMetaData.ABI + +// ExampleRewardCalculatorBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ExampleRewardCalculatorMetaData.Bin instead. +var ExampleRewardCalculatorBin = ExampleRewardCalculatorMetaData.Bin + +// DeployExampleRewardCalculator deploys a new Ethereum contract, binding an instance of ExampleRewardCalculator to it. +func DeployExampleRewardCalculator(auth *bind.TransactOpts, backend bind.ContractBackend, rewardBasisPoints_ uint64) (common.Address, *types.Transaction, *ExampleRewardCalculator, error) { + parsed, err := ExampleRewardCalculatorMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ExampleRewardCalculatorBin), backend, rewardBasisPoints_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ExampleRewardCalculator{ExampleRewardCalculatorCaller: ExampleRewardCalculatorCaller{contract: contract}, ExampleRewardCalculatorTransactor: ExampleRewardCalculatorTransactor{contract: contract}, ExampleRewardCalculatorFilterer: ExampleRewardCalculatorFilterer{contract: contract}}, nil +} + +// ExampleRewardCalculator is an auto generated Go binding around an Ethereum contract. +type ExampleRewardCalculator struct { + ExampleRewardCalculatorCaller // Read-only binding to the contract + ExampleRewardCalculatorTransactor // Write-only binding to the contract + ExampleRewardCalculatorFilterer // Log filterer for contract events +} + +// ExampleRewardCalculatorCaller is an auto generated read-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleRewardCalculatorTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleRewardCalculatorFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ExampleRewardCalculatorFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleRewardCalculatorSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ExampleRewardCalculatorSession struct { + Contract *ExampleRewardCalculator // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleRewardCalculatorCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ExampleRewardCalculatorCallerSession struct { + Contract *ExampleRewardCalculatorCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ExampleRewardCalculatorTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ExampleRewardCalculatorTransactorSession struct { + Contract *ExampleRewardCalculatorTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleRewardCalculatorRaw is an auto generated low-level Go binding around an Ethereum contract. +type ExampleRewardCalculatorRaw struct { + Contract *ExampleRewardCalculator // Generic contract binding to access the raw methods on +} + +// ExampleRewardCalculatorCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorCallerRaw struct { + Contract *ExampleRewardCalculatorCaller // Generic read-only contract binding to access the raw methods on +} + +// ExampleRewardCalculatorTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorTransactorRaw struct { + Contract *ExampleRewardCalculatorTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewExampleRewardCalculator creates a new instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculator(address common.Address, backend bind.ContractBackend) (*ExampleRewardCalculator, error) { + contract, err := bindExampleRewardCalculator(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ExampleRewardCalculator{ExampleRewardCalculatorCaller: ExampleRewardCalculatorCaller{contract: contract}, ExampleRewardCalculatorTransactor: ExampleRewardCalculatorTransactor{contract: contract}, ExampleRewardCalculatorFilterer: ExampleRewardCalculatorFilterer{contract: contract}}, nil +} + +// NewExampleRewardCalculatorCaller creates a new read-only instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculatorCaller(address common.Address, caller bind.ContractCaller) (*ExampleRewardCalculatorCaller, error) { + contract, err := bindExampleRewardCalculator(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ExampleRewardCalculatorCaller{contract: contract}, nil +} + +// NewExampleRewardCalculatorTransactor creates a new write-only instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculatorTransactor(address common.Address, transactor bind.ContractTransactor) (*ExampleRewardCalculatorTransactor, error) { + contract, err := bindExampleRewardCalculator(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ExampleRewardCalculatorTransactor{contract: contract}, nil +} + +// NewExampleRewardCalculatorFilterer creates a new log filterer instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculatorFilterer(address common.Address, filterer bind.ContractFilterer) (*ExampleRewardCalculatorFilterer, error) { + contract, err := bindExampleRewardCalculator(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ExampleRewardCalculatorFilterer{contract: contract}, nil +} + +// bindExampleRewardCalculator binds a generic wrapper to an already deployed contract. +func bindExampleRewardCalculator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ExampleRewardCalculatorMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleRewardCalculator *ExampleRewardCalculatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleRewardCalculator.Contract.ExampleRewardCalculatorCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleRewardCalculator *ExampleRewardCalculatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.ExampleRewardCalculatorTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleRewardCalculator *ExampleRewardCalculatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.ExampleRewardCalculatorTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleRewardCalculator.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleRewardCalculator *ExampleRewardCalculatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleRewardCalculator *ExampleRewardCalculatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.contract.Transact(opts, method, params...) +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) BIPSCONVERSIONFACTOR(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "BIPS_CONVERSION_FACTOR") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) BIPSCONVERSIONFACTOR() (uint16, error) { + return _ExampleRewardCalculator.Contract.BIPSCONVERSIONFACTOR(&_ExampleRewardCalculator.CallOpts) +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) BIPSCONVERSIONFACTOR() (uint16, error) { + return _ExampleRewardCalculator.Contract.BIPSCONVERSIONFACTOR(&_ExampleRewardCalculator.CallOpts) +} + +// SECONDSINYEAR is a free data retrieval call binding the contract method 0x5dcc9391. +// +// Solidity: function SECONDS_IN_YEAR() view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) SECONDSINYEAR(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "SECONDS_IN_YEAR") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SECONDSINYEAR is a free data retrieval call binding the contract method 0x5dcc9391. +// +// Solidity: function SECONDS_IN_YEAR() view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) SECONDSINYEAR() (*big.Int, error) { + return _ExampleRewardCalculator.Contract.SECONDSINYEAR(&_ExampleRewardCalculator.CallOpts) +} + +// SECONDSINYEAR is a free data retrieval call binding the contract method 0x5dcc9391. +// +// Solidity: function SECONDS_IN_YEAR() view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) SECONDSINYEAR() (*big.Int, error) { + return _ExampleRewardCalculator.Contract.SECONDSINYEAR(&_ExampleRewardCalculator.CallOpts) +} + +// UPTIMEREWARDSTHRESHOLDPERCENTAGE is a free data retrieval call binding the contract method 0xafba878a. +// +// Solidity: function UPTIME_REWARDS_THRESHOLD_PERCENTAGE() view returns(uint8) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) UPTIMEREWARDSTHRESHOLDPERCENTAGE(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "UPTIME_REWARDS_THRESHOLD_PERCENTAGE") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// UPTIMEREWARDSTHRESHOLDPERCENTAGE is a free data retrieval call binding the contract method 0xafba878a. +// +// Solidity: function UPTIME_REWARDS_THRESHOLD_PERCENTAGE() view returns(uint8) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) UPTIMEREWARDSTHRESHOLDPERCENTAGE() (uint8, error) { + return _ExampleRewardCalculator.Contract.UPTIMEREWARDSTHRESHOLDPERCENTAGE(&_ExampleRewardCalculator.CallOpts) +} + +// UPTIMEREWARDSTHRESHOLDPERCENTAGE is a free data retrieval call binding the contract method 0xafba878a. +// +// Solidity: function UPTIME_REWARDS_THRESHOLD_PERCENTAGE() view returns(uint8) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) UPTIMEREWARDSTHRESHOLDPERCENTAGE() (uint8, error) { + return _ExampleRewardCalculator.Contract.UPTIMEREWARDSTHRESHOLDPERCENTAGE(&_ExampleRewardCalculator.CallOpts) +} + +// CalculateReward is a free data retrieval call binding the contract method 0x4f22429f. +// +// Solidity: function calculateReward(uint256 stakeAmount, uint64 validatorStartTime, uint64 stakingStartTime, uint64 stakingEndTime, uint64 uptimeSeconds) view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) CalculateReward(opts *bind.CallOpts, stakeAmount *big.Int, validatorStartTime uint64, stakingStartTime uint64, stakingEndTime uint64, uptimeSeconds uint64) (*big.Int, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "calculateReward", stakeAmount, validatorStartTime, stakingStartTime, stakingEndTime, uptimeSeconds) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculateReward is a free data retrieval call binding the contract method 0x4f22429f. +// +// Solidity: function calculateReward(uint256 stakeAmount, uint64 validatorStartTime, uint64 stakingStartTime, uint64 stakingEndTime, uint64 uptimeSeconds) view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) CalculateReward(stakeAmount *big.Int, validatorStartTime uint64, stakingStartTime uint64, stakingEndTime uint64, uptimeSeconds uint64) (*big.Int, error) { + return _ExampleRewardCalculator.Contract.CalculateReward(&_ExampleRewardCalculator.CallOpts, stakeAmount, validatorStartTime, stakingStartTime, stakingEndTime, uptimeSeconds) +} + +// CalculateReward is a free data retrieval call binding the contract method 0x4f22429f. +// +// Solidity: function calculateReward(uint256 stakeAmount, uint64 validatorStartTime, uint64 stakingStartTime, uint64 stakingEndTime, uint64 uptimeSeconds) view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) CalculateReward(stakeAmount *big.Int, validatorStartTime uint64, stakingStartTime uint64, stakingEndTime uint64, uptimeSeconds uint64) (*big.Int, error) { + return _ExampleRewardCalculator.Contract.CalculateReward(&_ExampleRewardCalculator.CallOpts, stakeAmount, validatorStartTime, stakingStartTime, stakingEndTime, uptimeSeconds) +} + +// RewardBasisPoints is a free data retrieval call binding the contract method 0xbb65b242. +// +// Solidity: function rewardBasisPoints() view returns(uint64) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) RewardBasisPoints(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "rewardBasisPoints") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// RewardBasisPoints is a free data retrieval call binding the contract method 0xbb65b242. +// +// Solidity: function rewardBasisPoints() view returns(uint64) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) RewardBasisPoints() (uint64, error) { + return _ExampleRewardCalculator.Contract.RewardBasisPoints(&_ExampleRewardCalculator.CallOpts) +} + +// RewardBasisPoints is a free data retrieval call binding the contract method 0xbb65b242. +// +// Solidity: function rewardBasisPoints() view returns(uint64) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) RewardBasisPoints() (uint64, error) { + return _ExampleRewardCalculator.Contract.RewardBasisPoints(&_ExampleRewardCalculator.CallOpts) +} diff --git a/abi-bindings/go/validator-manager/NativeTokenStakingManager/NativeTokenStakingManager.go b/abi-bindings/go/validator-manager/NativeTokenStakingManager/NativeTokenStakingManager.go new file mode 100644 index 000000000..fa7e9cbc8 --- /dev/null +++ b/abi-bindings/go/validator-manager/NativeTokenStakingManager/NativeTokenStakingManager.go @@ -0,0 +1,3226 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokenstakingmanager + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ConversionData is an auto generated low-level Go binding around an user-defined struct. +type ConversionData struct { + SubnetID [32]byte + ValidatorManagerBlockchainID [32]byte + ValidatorManagerAddress common.Address + InitialValidators []InitialValidator +} + +// Delegator is an auto generated low-level Go binding around an user-defined struct. +type Delegator struct { + Status uint8 + Owner common.Address + ValidationID [32]byte + Weight uint64 + StartTime uint64 + StartingNonce uint64 + EndingNonce uint64 +} + +// InitialValidator is an auto generated low-level Go binding around an user-defined struct. +type InitialValidator struct { + NodeID []byte + BlsPublicKey []byte + Weight uint64 +} + +// PChainOwner is an auto generated low-level Go binding around an user-defined struct. +type PChainOwner struct { + Threshold uint32 + Addresses []common.Address +} + +// PoSValidatorInfo is an auto generated low-level Go binding around an user-defined struct. +type PoSValidatorInfo struct { + Owner common.Address + DelegationFeeBips uint16 + MinStakeDuration uint64 + UptimeSeconds uint64 +} + +// StakingManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type StakingManagerSettings struct { + Manager common.Address + MinimumStakeAmount *big.Int + MaximumStakeAmount *big.Int + MinimumStakeDuration uint64 + MinimumDelegationFeeBips uint16 + MaximumStakeMultiplier uint8 + WeightToValueFactor *big.Int + RewardCalculator common.Address + UptimeBlockchainID [32]byte +} + +// ValidatorMessagesValidationPeriod is an auto generated low-level Go binding around an user-defined struct. +type ValidatorMessagesValidationPeriod struct { + SubnetID [32]byte + NodeID []byte + BlsPublicKey []byte + RegistrationExpiry uint64 + RemainingBalanceOwner PChainOwner + DisableOwner PChainOwner + Weight uint64 +} + +// NativeTokenStakingManagerMetaData contains all meta data concerning the NativeTokenStakingManager contract. +var NativeTokenStakingManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"enumICMInitializable\",\"name\":\"init\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"DelegatorIneligibleForRewards\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"}],\"name\":\"InvalidDelegationFee\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"InvalidDelegationID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumDelegatorStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"InvalidDelegatorStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"}],\"name\":\"InvalidMinStakeDuration\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InvalidRewardRecipient\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"stakeAmount\",\"type\":\"uint256\"}],\"name\":\"InvalidStakeAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\"}],\"name\":\"InvalidStakeMultiplier\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"uptimeBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"InvalidUptimeBlockchainID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumValidatorStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"InvalidValidatorStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWarpMessage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"InvalidWarpOriginSenderAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceChainID\",\"type\":\"bytes32\"}],\"name\":\"InvalidWarpSourceChainID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"newValidatorWeight\",\"type\":\"uint64\"}],\"name\":\"MaxWeightExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"endTime\",\"type\":\"uint64\"}],\"name\":\"MinStakeDurationNotPassed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"UnauthorizedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expectedValidationID\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedValidationID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"ValidatorIneligibleForRewards\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"ValidatorNotPoS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroWeightToValueFactor\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startTime\",\"type\":\"uint256\"}],\"name\":\"CompletedDelegatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"}],\"name\":\"CompletedDelegatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DelegatorRewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"}],\"name\":\"DelegatorRewardRecipientChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegatorAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"validatorWeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"delegatorWeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"setWeightMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InitiatedDelegatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"InitiatedDelegatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InitiatedStakingValidatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"uptime\",\"type\":\"uint64\"}],\"name\":\"UptimeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ValidatorRewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"}],\"name\":\"ValidatorRewardRecipientChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BIPS_CONVERSION_FACTOR\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_DELEGATION_FEE_BIPS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_STAKE_MULTIPLIER_LIMIT\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NATIVE_MINTER\",\"outputs\":[{\"internalType\":\"contractINativeMinter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STAKING_MANAGER_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WARP_MESSENGER\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"changeDelegatorRewardRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"changeValidatorRewardRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"claimDelegationFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeDelegatorRegistration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRemoval\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"forceInitiateDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"forceInitiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"getDelegatorInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"enumDelegatorStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"startTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"startingNonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"endingNonce\",\"type\":\"uint64\"}],\"internalType\":\"structDelegator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"getDelegatorRewardInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStakingManagerSettings\",\"outputs\":[{\"components\":[{\"internalType\":\"contractIValidatorManager\",\"name\":\"manager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minimumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"minimumStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"minimumDelegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"weightToValueFactor\",\"type\":\"uint256\"},{\"internalType\":\"contractIRewardCalculator\",\"name\":\"rewardCalculator\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uptimeBlockchainID\",\"type\":\"bytes32\"}],\"internalType\":\"structStakingManagerSettings\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"getStakingValidator\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"uptimeSeconds\",\"type\":\"uint64\"}],\"internalType\":\"structPoSValidatorInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"getValidatorRewardInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contractIValidatorManager\",\"name\":\"manager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"minimumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maximumStakeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"minimumStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"minimumDelegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"weightToValueFactor\",\"type\":\"uint256\"},{\"internalType\":\"contractIRewardCalculator\",\"name\":\"rewardCalculator\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"uptimeBlockchainID\",\"type\":\"bytes32\"}],\"internalType\":\"structStakingManagerSettings\",\"name\":\"settings\",\"type\":\"tuple\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"initiateDelegatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initiateDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"initiateValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"resendUpdateDelegator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"submitUptimeProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"valueToWeight\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"weightToValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161418c38038061418c83398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b61403f8061014d5f395ff3fe6080604052600436106101ba575f3560e01c806360ad7784116100f2578063a9778a7a11610092578063b771b3bc11610062578063b771b3bc1461056b578063caa7187414610585578063e24b2680146105a6578063fb8b11dd146105c5575f80fd5b8063a9778a7a146103ba578063ad93936d146104fb578063af1dd66c1461050e578063b2c1712e1461054c575f80fd5b80638ef34c98116100cd5780638ef34c981461047f57806393e245981461049e5780639681d940146104bd578063a3a65e48146104dc575f80fd5b806360ad77841461040e578063620658561461042d5780637a63ad851461044c575f80fd5b80632674874b1161015d5780632e2194d8116101385780632e2194d814610351578063329c3e121461038857806335455ded146103ba57806353a13338146103e2575f80fd5b80632674874b146102a757806327bf60cd146103135780632aa5663814610332575f80fd5b806316679564116101985780631667956414610229578063243ca19a14610248578063245dafcb1461026957806325e1c77614610288575f80fd5b80630d436317146101be57806313409645146101df578063151d30d1146101fe575b5f80fd5b3480156101c9575f80fd5b506101dd6101d8366004613583565b6105e4565b005b3480156101ea575f80fd5b506101dd6101f93660046135ad565b6106f0565b348015610209575f80fd5b50610212600a81565b60405160ff90911681526020015b60405180910390f35b348015610234575f80fd5b506101dd6102433660046135e4565b610a30565b61025b61025636600461363e565b610a41565b604051908152602001610220565b348015610274575f80fd5b506101dd61028336600461366c565b610a74565b348015610293575f80fd5b506101dd6102a23660046135ad565b610d38565b3480156102b2575f80fd5b506102c66102c136600461366c565b610e16565b6040805182516001600160a01b0316815260208084015161ffff1690820152828201516001600160401b039081169282019290925260609283015190911691810191909152608001610220565b34801561031e575f80fd5b506101dd61032d3660046135e4565b610ea2565b34801561033d575f80fd5b506101dd61034c3660046135e4565b610ead565b34801561035c575f80fd5b5061037061036b36600461366c565b610ebd565b6040516001600160401b039091168152602001610220565b348015610393575f80fd5b506103a26001600160991b0181565b6040516001600160a01b039091168152602001610220565b3480156103c5575f80fd5b506103cf61271081565b60405161ffff9091168152602001610220565b3480156103ed575f80fd5b506104016103fc36600461366c565b610f0b565b60405161022091906136ab565b348015610419575f80fd5b506101dd6104283660046135ad565b610ff8565b348015610438575f80fd5b5061025b610447366004613739565b611312565b348015610457575f80fd5b5061025b7fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60081565b34801561048a575f80fd5b506101dd61049936600461363e565b611332565b3480156104a9575f80fd5b506101dd6104b836600461366c565b611414565b3480156104c8575f80fd5b5061025b6104d7366004613754565b61152d565b3480156104e7575f80fd5b5061025b6104f6366004613754565b6116ce565b61025b61050936600461394e565b611746565b348015610519575f80fd5b5061052d61052836600461366c565b611782565b604080516001600160a01b039093168352602083019190915201610220565b348015610557575f80fd5b506101dd6105663660046135e4565b6117be565b348015610576575f80fd5b506103a26005600160991b0181565b348015610590575f80fd5b506105996117c9565b6040516102209190613a23565b3480156105b1575f80fd5b5061052d6105c036600461366c565b6118a5565b3480156105d0575f80fd5b506101dd6105df36600461363e565b6118e1565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156106285750825b90505f826001600160401b031660011480156106435750303b155b905081158015610651575080155b1561066f5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561069957845460ff60401b1916600160401b1785555b6106a2866119a9565b83156106e857845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b6106f86119bd565b5f6107016119f4565b5f848152600882016020526040808220815160e0810190925280549394509192909190829060ff16600381111561073a5761073a613683565b600381111561074b5761074b613683565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015290506003815160038111156107c4576107c4613683565b146107ee578051604051633b0d540d60e21b81526107e59190600401613ac4565b60405180910390fd5b81546040828101519051636af907fb60e11b815260048101919091525f916001600160a01b03169063d5f20ff6906024015f60405180830381865afa158015610839573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108609190810190613b57565b9050600483546040808501519051636af907fb60e11b81526001600160a01b039092169163d5f20ff69161089a9160040190815260200190565b5f60405180830381865afa1580156108b4573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108db9190810190613b57565b5160058111156108ed576108ed613683565b1415801561091457508160c001516001600160401b031681608001516001600160401b0316105b15610a0a57825460405163338587c560e21b815263ffffffff861660048201525f9182916001600160a01b039091169063ce161f149060240160408051808303815f875af1158015610968573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098c9190613c36565b91509150818460400151146109c55781846040015160405163fee3144560e01b81526004016107e5929190918252602082015260400190565b806001600160401b03168460c001516001600160401b03161115610a0757604051632e19bc2d60e11b81526001600160401b03821660048201526024016107e5565b50505b610a1385611a18565b505050610a2c60015f80516020613fea83398151915255565b5050565b610a3b838383611c5c565b50505050565b5f610a4a6119bd565b610a5683333485611f03565b9050610a6e60015f80516020613fea83398151915255565b92915050565b5f610a7d6119f4565b5f838152600882016020526040808220815160e0810190925280549394509192909190829060ff166003811115610ab657610ab6613683565b6003811115610ac757610ac7613683565b8152815461010090046001600160a01b0316602082015260018083015460408301526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015290915081516003811115610b4057610b40613683565b14158015610b615750600381516003811115610b5e57610b5e613683565b14155b15610b82578051604051633b0d540d60e21b81526107e59190600401613ac4565b81546040828101519051636af907fb60e11b815260048101919091525f916001600160a01b03169063d5f20ff6906024015f60405180830381865afa158015610bcd573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610bf49190810190613b57565b905080606001516001600160401b03165f03610c26576040516339b894f960e21b8152600481018590526024016107e5565b604080830151606083015160a0840151925163854a893f60e01b81526005600160991b019363ee5b48eb9373__$16907f4f2c19a387278bf4c8803bf9f1c2$__9363854a893f93610c9493906004019283526001600160401b03918216602084015216604082015260600190565b5f60405180830381865af4158015610cae573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610cd59190810190613c59565b6040518263ffffffff1660e01b8152600401610cf19190613cb5565b6020604051808303815f875af1158015610d0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d319190613cc7565b5050505050565b610d418261234a565b610d61576040516330efa98b60e01b8152600481018390526024016107e5565b5f610d6a6119f4565b54604051636af907fb60e11b8152600481018590526001600160a01b039091169063d5f20ff6906024015f60405180830381865afa158015610dae573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610dd59190810190613b57565b5190506002816005811115610dec57610dec613683565b14610e0c578060405163170cc93360e21b81526004016107e59190613cde565b610a3b8383612373565b604080516080810182525f808252602082018190529181018290526060810191909152610e416119f4565b5f9283526007016020908152604092839020835160808101855281546001600160a01b038116825261ffff600160a01b820416938201939093526001600160401b03600160b01b909304831694810194909452600101541660608301525090565b610a3b8383836125da565b610eb88383836129fb565b505050565b5f80610ec76119f4565b60040154610ed59084613d0c565b9050801580610eea57506001600160401b0381115b15610a6e5760405163222d164360e21b8152600481018490526024016107e5565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152610f4b6119f4565b5f838152600891909101602052604090819020815160e081019092528054829060ff166003811115610f7f57610f7f613683565b6003811115610f9057610f90613683565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015292915050565b5f6110016119f4565b5f848152600882016020526040808220815160e0810190925280549394509192909190829060ff16600381111561103a5761103a613683565b600381111561104b5761104b613683565b8152815461010090046001600160a01b03908116602083015260018301546040808401919091526002909301546001600160401b038082166060850152600160401b820481166080850152600160801b8204811660a0850152600160c01b9091041660c0909201919091528282015185549251636af907fb60e11b815260048101829052939450925f929091169063d5f20ff6906024015f60405180830381865afa1580156110fc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526111239190810190613b57565b905060018351600381111561113a5761113a613683565b1461115b578251604051633b0d540d60e21b81526107e59190600401613ac4565b60048151600581111561117057611170613683565b0361117e576106e886611a18565b8260a001516001600160401b031681608001516001600160401b0316101561128657835460405163338587c560e21b815263ffffffff871660048201525f9182916001600160a01b039091169063ce161f149060240160408051808303815f875af11580156111ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112139190613c36565b915091508184146112415760405163fee3144560e01b815260048101839052602481018590526044016107e5565b8460a001516001600160401b0316816001600160401b0316101561128357604051632e19bc2d60e11b81526001600160401b03821660048201526024016107e5565b50505b5f868152600885016020908152604091829020805460ff1916600290811782550180546001600160401b034216600160401b81026fffffffffffffffff000000000000000019909216919091179091559151918252839188917f3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa910160405180910390a3505050505050565b5f61131b6119f4565b60040154610a6e906001600160401b038416613d2b565b5f61133b6119f4565b90506001600160a01b03821661136f5760405163caa903f960e01b81526001600160a01b03831660048201526024016107e5565b5f8381526007820160205260409020546001600160a01b031633146113b557335b604051636e2ccd7560e11b81526001600160a01b0390911660048201526024016107e5565b5f838152600c8201602052604080822080546001600160a01b038681166001600160a01b0319831681179093559251921692839287917f28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c3391a450505050565b5f61141d6119f4565b8054604051636af907fb60e11b8152600481018590529192505f916001600160a01b039091169063d5f20ff6906024015f60405180830381865afa158015611467573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261148e9190810190613b57565b51905060048160058111156114a5576114a5613683565b146114c5578060405163170cc93360e21b81526004016107e59190613cde565b5f8381526007830160205260409020546001600160a01b031633146114ea5733611390565b5f838152600c830160205260409020546001600160a01b03168061152357505f8381526007830160205260409020546001600160a01b03165b610a3b8185612a26565b5f6115366119bd565b5f61153f6119f4565b805460405163025a076560e61b815263ffffffff861660048201529192505f916001600160a01b0390911690639681d940906024016020604051808303815f875af1158015611590573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115b49190613cc7565b8254604051636af907fb60e11b8152600481018390529192505f916001600160a01b039091169063d5f20ff6906024015f60405180830381865afa1580156115fe573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526116259190810190613b57565b90506116308261234a565b61163e575091506116b39050565b5f828152600784016020908152604080832054600c8701909252909120546001600160a01b039182169116806116715750805b60048351600581111561168657611686613683565b03611695576116958185612a26565b6116ab826116a68560400151611312565b612a9a565b509193505050505b6116c960015f80516020613fea83398151915255565b919050565b5f6116d76119f4565b54604051631474cbc960e31b815263ffffffff841660048201526001600160a01b039091169063a3a65e48906024016020604051808303815f875af1158015611722573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a6e9190613cc7565b5f61174f6119bd565b61175f8888888888883489612aad565b905061177760015f80516020613fea83398151915255565b979650505050505050565b5f805f61178d6119f4565b5f948552600a810160209081526040808720546009909301909152909420546001600160a01b039094169492505050565b610eb8838383612dd9565b60408051610120810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052906118196119f4565b604080516101208101825282546001600160a01b0390811682526001840154602083015260028401549282019290925260038301546001600160401b0381166060830152600160401b810461ffff166080830152600160501b900460ff1660a0820152600483015460c0820152600583015490911660e082015260069091015461010082015292915050565b5f805f6118b06119f4565b5f948552600c81016020908152604080872054600b909301909152909420546001600160a01b039094169492505050565b6001600160a01b0381166119135760405163caa903f960e01b81526001600160a01b03821660048201526024016107e5565b5f61191c6119f4565b5f8481526008820160205260409020549091506001600160a01b0361010090910416331461194a5733611390565b5f838152600a8201602052604080822080546001600160a01b038681166001600160a01b0319831681179093559251921692839287917f6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e00591a450505050565b6119b1612e04565b6119ba81612e4f565b50565b5f80516020613fea8339815191528054600119016119ee57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b7fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60090565b5f611a216119f4565b5f838152600882016020526040808220815160e0810190925280549394509192909190829060ff166003811115611a5a57611a5a613683565b6003811115611a6b57611a6b613683565b815281546001600160a01b03610100909104811660208084019190915260018401546040808501919091526002909401546001600160401b038082166060860152600160401b820481166080860152600160801b8204811660a0860152600160c01b9091041660c09093019290925283830151865484516304e0efb360e11b8152945195965090949116926309c1df669260048083019391928290030181865afa158015611b1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b3f9190613d42565b8260800151611b4e9190613d5d565b6001600160401b0316421015611b825760405163fb6ce63f60e01b81526001600160401b03421660048201526024016107e5565b5f848152600884016020908152604080832080546001600160a81b031916815560018101849055600201839055600a8601909152902080546001600160a01b031981169091556001600160a01b031680611bdd575060208201515b5f80611bea838886612eca565b91509150611c0385602001516116a68760600151611312565b6040805183815260208101839052859189917f5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e910160405180910390a350505050505050565b60015f80516020613fea83398151915255565b5f80611c666119f4565b8054604051635b73516560e11b8152600481018890529192506001600160a01b03169063b6e6a2ca906024015f604051808303815f87803b158015611ca9575f80fd5b505af1158015611cbb573d5f803e3d5ffd5b50508254604051636af907fb60e11b8152600481018990525f93506001600160a01b03909116915063d5f20ff6906024015f60405180830381865afa158015611d06573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611d2d9190810190613b57565b9050611d388661234a565b611d4757600192505050611efc565b5f8681526007830160205260409020546001600160a01b03163314611d6c5733611390565b5f86815260078301602052604090205460c0820151611d9b91600160b01b90046001600160401b031690613d5d565b6001600160401b03168160e001516001600160401b03161015611de25760e081015160405163fb6ce63f60e01b81526001600160401b0390911660048201526024016107e5565b5f8515611dfa57611df38786612373565b9050611e18565b505f8681526007830160205260409020600101546001600160401b03165b600583015460408301515f916001600160a01b031690634f22429f90611e3d90611312565b60c086015160e0808801516040519185901b6001600160e01b031916825260048201939093526001600160401b0391821660248201819052604482015291811660648301528516608482015260a401602060405180830381865afa158015611ea7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecb9190613cc7565b90508084600b015f8a81526020019081526020015f205f828254611eef9190613d84565b9091555050151593505050505b9392505050565b5f80611f0d6119f4565b90505f611f1985610ebd565b9050611f248761234a565b611f44576040516330efa98b60e01b8152600481018890526024016107e5565b6001600160a01b038416611f765760405163caa903f960e01b81526001600160a01b03851660048201526024016107e5565b8154604051636af907fb60e11b8152600481018990525f9182916001600160a01b039091169063d5f20ff6906024015f60405180830381865afa158015611fbf573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611fe69190810190613b57565b9050828160a00151611ff89190613d5d565b915083600301600a9054906101000a90046001600160401b031681604001516120219190613d97565b6001600160401b0316826001600160401b0316111561205e57604051636d51fe0560e11b81526001600160401b03831660048201526024016107e5565b508254604051636610966960e01b8152600481018a90526001600160401b03831660248201525f9182916001600160a01b039091169063661096699060440160408051808303815f875af11580156120b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120dc9190613dc2565b915091505f8a8360405160200161210a92919091825260c01b6001600160c01b031916602082015260280190565b60408051601f1981840301815291815281516020928301205f81815260088a019093529120805491925060019160ff19168280021790555089866008015f8381526020019081526020015f205f0160016101000a8154816001600160a01b0302191690836001600160a01b031602179055508a866008015f8381526020019081526020015f206001018190555084866008015f8381526020019081526020015f206002015f6101000a8154816001600160401b0302191690836001600160401b031602179055505f866008015f8381526020019081526020015f2060020160086101000a8154816001600160401b0302191690836001600160401b0316021790555082866008015f8381526020019081526020015f2060020160106101000a8154816001600160401b0302191690836001600160401b031602179055505f866008015f8381526020019081526020015f2060020160186101000a8154816001600160401b0302191690836001600160401b031602179055508786600a015f8381526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550896001600160a01b03168b827f77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d7786888a888f6040516123349594939291906001600160401b039586168152938516602085015291909316604083015260608201929092526001600160a01b0391909116608082015260a00190565b60405180910390a49a9950505050505050505050565b5f806123546119f4565b5f938452600701602052505060409020546001600160a01b0316151590565b6040516306f8253560e41b815263ffffffff821660048201525f90819081906005600160991b0190636f825350906024015f60405180830381865afa1580156123be573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526123e59190810190613dee565b915091508061240757604051636b2f19e960e01b815260040160405180910390fd5b5f6124106119f4565b600681015484519192501461243e578251604051636ba589a560e01b815260048101919091526024016107e5565b60208301516001600160a01b03161561247a576020830151604051624de75d60e31b81526001600160a01b0390911660048201526024016107e5565b5f8073__$16907f4f2c19a387278bf4c8803bf9f1c2$__63088c246386604001516040518263ffffffff1660e01b81526004016124b79190613cb5565b6040805180830381865af41580156124d1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124f59190613c36565b915091508188146125235760405163fee3144560e01b815260048101839052602481018990526044016107e5565b5f8881526007840160205260409020600101546001600160401b0390811690821611156125b4575f888152600784016020908152604091829020600101805467ffffffffffffffff19166001600160401b038516908117909155915191825289917fec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435910160405180910390a2611777565b50505f95865260070160205250506040909220600101546001600160401b031692915050565b5f806125e46119f4565b5f868152600882016020526040808220815160e0810190925280549394509192909190829060ff16600381111561261d5761261d613683565b600381111561262e5761262e613683565b8152815461010090046001600160a01b03908116602083015260018301546040808401919091526002909301546001600160401b038082166060850152600160401b820481166080850152600160801b8204811660a0850152600160c01b9091041660c0909201919091528282015185549251636af907fb60e11b815260048101829052939450925f929091169063d5f20ff6906024015f60405180830381865afa1580156126df573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526127069190810190613b57565b905060028351600381111561271d5761271d613683565b1461273e578251604051633b0d540d60e21b81526107e59190600401613ac4565b60208301516001600160a01b031633146127da575f8281526007850160205260409020546001600160a01b031633146127775733611390565b5f82815260078501602052604090205460c08201516127a691600160b01b90046001600160401b031690613d5d565b6001600160401b03164210156127da5760405163fb6ce63f60e01b81526001600160401b03421660048201526024016107e5565b5f888152600a850160205260409020546001600160a01b031660028251600581111561280857612808613683565b036129a2576003850154608085015161282a916001600160401b031690613d5d565b6001600160401b031642101561285e5760405163fb6ce63f60e01b81526001600160401b03421660048201526024016107e5565b87156128705761286e8388612373565b505b5f8981526008860160205260409020805460ff191660031790558454606085015160a08401516001600160a01b039092169163661096699186916128b49190613e94565b6040516001600160e01b031960e085901b16815260048101929092526001600160401b0316602482015260440160408051808303815f875af11580156128fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129209190613dc2565b505f8a8152600887016020526040812060020180546001600160401b03909316600160c01b026001600160c01b039093169290921790915561296385838c612fc9565b9050838a7f5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf60405160405180910390a315159550611efc945050505050565b6004825160058111156129b7576129b7613683565b036129df576129c784828b612fc9565b506129d189611a18565b600195505050505050611efc565b815160405163170cc93360e21b81526107e59190600401613cde565b612a068383836125da565b610eb857604051631036cf9160e11b8152600481018490526024016107e5565b5f612a2f6119f4565b5f838152600b8201602052604081208054919055909150612a508482613203565b836001600160a01b0316837f875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e483604051612a8c91815260200190565b60405180910390a350505050565b610a2c6001600160a01b03831682613261565b5f80612ab76119f4565b600381015490915061ffff600160401b90910481169087161080612ae0575061271061ffff8716115b15612b0457604051635f12e6c360e11b815261ffff871660048201526024016107e5565b60038101546001600160401b039081169086161015612b40576040516202a06d60e11b81526001600160401b03861660048201526024016107e5565b8060010154841080612b555750806002015484115b15612b765760405163222d164360e21b8152600481018590526024016107e5565b6001600160a01b038316612ba85760405163caa903f960e01b81526001600160a01b03841660048201526024016107e5565b835f612bb382610ebd565b90505f835f015f9054906101000a90046001600160a01b03166001600160a01b0316639cb7624e8e8e8e8e876040518663ffffffff1660e01b8152600401612bff959493929190613f1a565b6020604051808303815f875af1158015612c1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c3f9190613cc7565b90505f33905080856007015f8481526020019081526020015f205f015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555089856007015f8481526020019081526020015f205f0160146101000a81548161ffff021916908361ffff16021790555088856007015f8481526020019081526020015f205f0160166101000a8154816001600160401b0302191690836001600160401b031602179055505f856007015f8481526020019081526020015f206001015f6101000a8154816001600160401b0302191690836001600160401b031602179055508685600c015f8481526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001600160a01b0316827ff51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f8c8c8b604051612dc09392919061ffff9390931683526001600160401b039190911660208301526001600160a01b0316604082015260600190565b60405180910390a3509c9b505050505050505050505050565b612de4838383611c5c565b610eb857604051635bff683f60e11b8152600481018490526024016107e5565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16612e4d57604051631afcd79f60e31b815260040160405180910390fd5b565b612e57612e04565b612e5f6132f4565b6119ba612e6f6020830183613f82565b60208301356040840135612e896080860160608701613739565b612e9960a0870160808801613f9d565b612ea960c0880160a08901613fb6565b60c0880135612ebf6101008a0160e08b01613f82565b896101000135613304565b5f805f612ed56119f4565b5f8681526009820160205260408120549192509081908015612fbb575f88815260098501602090815260408083208390558983526007870190915290205461271090612f2c90600160a01b900461ffff1683613d2b565b612f369190613d0c565b91508184600b015f8981526020019081526020015f205f828254612f5a9190613d84565b90915550612f6a90508282613fd6565b9250612f768984613203565b886001600160a01b0316887f3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf6385604051612fb291815260200190565b60405180910390a35b509097909650945050505050565b5f80612fd36119f4565b80546040808801519051636af907fb60e11b81529293505f926001600160a01b039092169163d5f20ff69161300e9160040190815260200190565b5f60405180830381865afa158015613028573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261304f9190810190613b57565b90505f60038251600581111561306757613067613683565b1480613085575060048251600581111561308357613083613683565b145b15613095575060e08101516130b2565b6002825160058111156130aa576130aa613683565b036129df5750425b86608001516001600160401b0316816001600160401b0316116130da575f9350505050611efc565b600583015460608801515f916001600160a01b031690634f22429f906130ff90611312565b60c086015160808c01516040808e01515f90815260078b0160205281902060010154905160e086901b6001600160e01b031916815260048101949094526001600160401b0392831660248501529082166044840152818716606484015216608482015260a401602060405180830381865afa158015613180573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131a49190613cc7565b90506001600160a01b0387166131bc57876020015196505b5f8681526009850160209081526040808320849055600a90960190529390932080546001600160a01b0388166001600160a01b031990911617905550909150509392505050565b6040516327ad555d60e11b81526001600160a01b0383166004820152602481018290526001600160991b0190634f5aaaba906044015f604051808303815f87803b15801561324f575f80fd5b505af11580156106e8573d5f803e3d5ffd5b804710156132845760405163cd78605960e01b81523060048201526024016107e5565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f81146132cd576040519150601f19603f3d011682016040523d82523d5f602084013e6132d2565b606091505b5050905080610eb857604051630a12f52160e11b815260040160405180910390fd5b6132fc612e04565b612e4d61357b565b61330c612e04565b5f6133156119f4565b905061ffff8616158061332d575061271061ffff8716115b1561335157604051635f12e6c360e11b815261ffff871660048201526024016107e5565b878911156133755760405163222d164360e21b8152600481018a90526024016107e5565b60ff851615806133885750600a60ff8616115b156133ab5760405163170db35960e31b815260ff861660048201526024016107e5565b6001600160a01b038a166133d25760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0383166133f95760405163d92e233d60e01b815260040160405180910390fd5b896001600160a01b03166309c1df666040518163ffffffff1660e01b8152600401602060405180830381865afa158015613435573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134599190613d42565b6001600160401b0316876001600160401b03161015613495576040516202a06d60e11b81526001600160401b03881660048201526024016107e5565b835f036134b55760405163a733007160e01b815260040160405180910390fd5b816134d657604051632f6bd1db60e01b8152600481018390526024016107e5565b80546001600160a01b039a8b166001600160a01b031991821617825560018201999099556002810197909755600387018054600160501b60ff9096169590950267ffffffffffffffff60501b1961ffff909716600160401b0269ffffffffffffffffffff199096166001600160401b03909816979097179490941794909416949094179091556004840155600583018054929095169190931617909255600690910155565b611c49612e04565b5f6101208284031215613594575f80fd5b50919050565b803563ffffffff811681146116c9575f80fd5b5f80604083850312156135be575f80fd5b823591506135ce6020840161359a565b90509250929050565b80151581146119ba575f80fd5b5f805f606084860312156135f6575f80fd5b833592506020840135613608816135d7565b91506136166040850161359a565b90509250925092565b6001600160a01b03811681146119ba575f80fd5b80356116c98161361f565b5f806040838503121561364f575f80fd5b8235915060208301356136618161361f565b809150509250929050565b5f6020828403121561367c575f80fd5b5035919050565b634e487b7160e01b5f52602160045260245ffd5b600481106136a7576136a7613683565b9052565b5f60e0820190506136bd828451613697565b60018060a01b0360208401511660208301526040830151604083015260608301516001600160401b0380821660608501528060808601511660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b6001600160401b03811681146119ba575f80fd5b80356116c98161371a565b5f60208284031215613749575f80fd5b8135611efc8161371a565b5f60208284031215613764575f80fd5b611efc8261359a565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156137a3576137a361376d565b60405290565b60405161010081016001600160401b03811182821017156137a3576137a361376d565b604051601f8201601f191681016001600160401b03811182821017156137f4576137f461376d565b604052919050565b5f6001600160401b038211156138145761381461376d565b50601f01601f191660200190565b5f82601f830112613831575f80fd5b813561384461383f826137fc565b6137cc565b818152846020838601011115613858575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60408284031215613884575f80fd5b61388c613781565b90506138978261359a565b81526020808301356001600160401b03808211156138b3575f80fd5b818501915085601f8301126138c6575f80fd5b8135818111156138d8576138d861376d565b8060051b91506138e98483016137cc565b8181529183018401918481019088841115613902575f80fd5b938501935b8385101561392c578435925061391c8361361f565b8282529385019390850190613907565b808688015250505050505092915050565b803561ffff811681146116c9575f80fd5b5f805f805f805f60e0888a031215613964575f80fd5b87356001600160401b038082111561397a575f80fd5b6139868b838c01613822565b985060208a013591508082111561399b575f80fd5b6139a78b838c01613822565b975060408a01359150808211156139bc575f80fd5b6139c88b838c01613874565b965060608a01359150808211156139dd575f80fd5b506139ea8a828b01613874565b9450506139f96080890161393d565b9250613a0760a0890161372e565b9150613a1560c08901613633565b905092959891949750929550565b81516001600160a01b031681526020808301519082015260408083015190820152606080830151610120830191613a64908401826001600160401b03169052565b506080830151613a7a608084018261ffff169052565b5060a0830151613a8f60a084018260ff169052565b5060c083015160c083015260e0830151613ab460e08401826001600160a01b03169052565b5061010092830151919092015290565b60208101610a6e8284613697565b8051600681106116c9575f80fd5b5f5b83811015613afa578181015183820152602001613ae2565b50505f910152565b5f82601f830112613b11575f80fd5b8151613b1f61383f826137fc565b818152846020838601011115613b33575f80fd5b613b44826020830160208701613ae0565b949350505050565b80516116c98161371a565b5f60208284031215613b67575f80fd5b81516001600160401b0380821115613b7d575f80fd5b908301906101008286031215613b91575f80fd5b613b996137a9565b613ba283613ad2565b8152602083015182811115613bb5575f80fd5b613bc187828601613b02565b602083015250613bd360408401613b4c565b6040820152613be460608401613b4c565b6060820152613bf560808401613b4c565b6080820152613c0660a08401613b4c565b60a0820152613c1760c08401613b4c565b60c0820152613c2860e08401613b4c565b60e082015295945050505050565b5f8060408385031215613c47575f80fd5b8251915060208301516136618161371a565b5f60208284031215613c69575f80fd5b81516001600160401b03811115613c7e575f80fd5b613b4484828501613b02565b5f8151808452613ca1816020860160208601613ae0565b601f01601f19169290920160200192915050565b602081525f611efc6020830184613c8a565b5f60208284031215613cd7575f80fd5b5051919050565b6020810160068310613cf257613cf2613683565b91905290565b634e487b7160e01b5f52601160045260245ffd5b5f82613d2657634e487b7160e01b5f52601260045260245ffd5b500490565b8082028115828204841417610a6e57610a6e613cf8565b5f60208284031215613d52575f80fd5b8151611efc8161371a565b6001600160401b03818116838216019080821115613d7d57613d7d613cf8565b5092915050565b80820180821115610a6e57610a6e613cf8565b6001600160401b03818116838216028082169190828114613dba57613dba613cf8565b505092915050565b5f8060408385031215613dd3575f80fd5b8251613dde8161371a565b6020939093015192949293505050565b5f8060408385031215613dff575f80fd5b82516001600160401b0380821115613e15575f80fd5b9084019060608287031215613e28575f80fd5b604051606081018181108382111715613e4357613e4361376d565b604052825181526020830151613e588161361f565b6020820152604083015182811115613e6e575f80fd5b613e7a88828601613b02565b6040830152508094505050506020830151613661816135d7565b6001600160401b03828116828216039080821115613d7d57613d7d613cf8565b5f6040830163ffffffff8351168452602080840151604060208701528281518085526060880191506020830194505f92505b80831015613f0f5784516001600160a01b03168252938301936001929092019190830190613ee6565b509695505050505050565b60a081525f613f2c60a0830188613c8a565b8281036020840152613f3e8188613c8a565b90508281036040840152613f528187613eb4565b90508281036060840152613f668186613eb4565b9150506001600160401b03831660808301529695505050505050565b5f60208284031215613f92575f80fd5b8135611efc8161361f565b5f60208284031215613fad575f80fd5b611efc8261393d565b5f60208284031215613fc6575f80fd5b813560ff81168114611efc575f80fd5b81810381811115610a6e57610a6e613cf856fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220649d652aad549f62f75442dd8e332eefcecbc05c9a4bbabf19ae331e77cfc09b64736f6c63430008190033", +} + +// NativeTokenStakingManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenStakingManagerMetaData.ABI instead. +var NativeTokenStakingManagerABI = NativeTokenStakingManagerMetaData.ABI + +// NativeTokenStakingManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenStakingManagerMetaData.Bin instead. +var NativeTokenStakingManagerBin = NativeTokenStakingManagerMetaData.Bin + +// DeployNativeTokenStakingManager deploys a new Ethereum contract, binding an instance of NativeTokenStakingManager to it. +func DeployNativeTokenStakingManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *NativeTokenStakingManager, error) { + parsed, err := NativeTokenStakingManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + validatorMessagesAddr, _, _, _ := DeployValidatorMessages(auth, backend) + NativeTokenStakingManagerBin = strings.ReplaceAll(NativeTokenStakingManagerBin, "__$16907f4f2c19a387278bf4c8803bf9f1c2$__", validatorMessagesAddr.String()[2:]) + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NativeTokenStakingManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenStakingManager{NativeTokenStakingManagerCaller: NativeTokenStakingManagerCaller{contract: contract}, NativeTokenStakingManagerTransactor: NativeTokenStakingManagerTransactor{contract: contract}, NativeTokenStakingManagerFilterer: NativeTokenStakingManagerFilterer{contract: contract}}, nil +} + +// NativeTokenStakingManager is an auto generated Go binding around an Ethereum contract. +type NativeTokenStakingManager struct { + NativeTokenStakingManagerCaller // Read-only binding to the contract + NativeTokenStakingManagerTransactor // Write-only binding to the contract + NativeTokenStakingManagerFilterer // Log filterer for contract events +} + +// NativeTokenStakingManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenStakingManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenStakingManagerSession struct { + Contract *NativeTokenStakingManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenStakingManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenStakingManagerCallerSession struct { + Contract *NativeTokenStakingManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenStakingManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenStakingManagerTransactorSession struct { + Contract *NativeTokenStakingManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenStakingManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenStakingManagerRaw struct { + Contract *NativeTokenStakingManager // Generic contract binding to access the raw methods on +} + +// NativeTokenStakingManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerCallerRaw struct { + Contract *NativeTokenStakingManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenStakingManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerTransactorRaw struct { + Contract *NativeTokenStakingManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenStakingManager creates a new instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManager(address common.Address, backend bind.ContractBackend) (*NativeTokenStakingManager, error) { + contract, err := bindNativeTokenStakingManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenStakingManager{NativeTokenStakingManagerCaller: NativeTokenStakingManagerCaller{contract: contract}, NativeTokenStakingManagerTransactor: NativeTokenStakingManagerTransactor{contract: contract}, NativeTokenStakingManagerFilterer: NativeTokenStakingManagerFilterer{contract: contract}}, nil +} + +// NewNativeTokenStakingManagerCaller creates a new read-only instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenStakingManagerCaller, error) { + contract, err := bindNativeTokenStakingManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerCaller{contract: contract}, nil +} + +// NewNativeTokenStakingManagerTransactor creates a new write-only instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenStakingManagerTransactor, error) { + contract, err := bindNativeTokenStakingManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerTransactor{contract: contract}, nil +} + +// NewNativeTokenStakingManagerFilterer creates a new log filterer instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenStakingManagerFilterer, error) { + contract, err := bindNativeTokenStakingManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerFilterer{contract: contract}, nil +} + +// bindNativeTokenStakingManager binds a generic wrapper to an already deployed contract. +func bindNativeTokenStakingManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenStakingManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenStakingManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.contract.Transact(opts, method, params...) +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) BIPSCONVERSIONFACTOR(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "BIPS_CONVERSION_FACTOR") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) BIPSCONVERSIONFACTOR() (uint16, error) { + return _NativeTokenStakingManager.Contract.BIPSCONVERSIONFACTOR(&_NativeTokenStakingManager.CallOpts) +} + +// BIPSCONVERSIONFACTOR is a free data retrieval call binding the contract method 0xa9778a7a. +// +// Solidity: function BIPS_CONVERSION_FACTOR() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) BIPSCONVERSIONFACTOR() (uint16, error) { + return _NativeTokenStakingManager.Contract.BIPSCONVERSIONFACTOR(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) MAXIMUMDELEGATIONFEEBIPS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "MAXIMUM_DELEGATION_FEE_BIPS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) MAXIMUMSTAKEMULTIPLIERLIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "MAXIMUM_STAKE_MULTIPLIER_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_NativeTokenStakingManager.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) NATIVEMINTER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "NATIVE_MINTER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.NATIVEMINTER(&_NativeTokenStakingManager.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.NATIVEMINTER(&_NativeTokenStakingManager.CallOpts) +} + +// STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0x7a63ad85. +// +// Solidity: function STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) STAKINGMANAGERSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "STAKING_MANAGER_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0x7a63ad85. +// +// Solidity: function STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) STAKINGMANAGERSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenStakingManager.Contract.STAKINGMANAGERSTORAGELOCATION(&_NativeTokenStakingManager.CallOpts) +} + +// STAKINGMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0x7a63ad85. +// +// Solidity: function STAKING_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) STAKINGMANAGERSTORAGELOCATION() ([32]byte, error) { + return _NativeTokenStakingManager.Contract.STAKINGMANAGERSTORAGELOCATION(&_NativeTokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) WARPMESSENGER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.WARPMESSENGER(&_NativeTokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.WARPMESSENGER(&_NativeTokenStakingManager.CallOpts) +} + +// GetDelegatorInfo is a free data retrieval call binding the contract method 0x53a13338. +// +// Solidity: function getDelegatorInfo(bytes32 delegationID) view returns((uint8,address,bytes32,uint64,uint64,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) GetDelegatorInfo(opts *bind.CallOpts, delegationID [32]byte) (Delegator, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "getDelegatorInfo", delegationID) + + if err != nil { + return *new(Delegator), err + } + + out0 := *abi.ConvertType(out[0], new(Delegator)).(*Delegator) + + return out0, err + +} + +// GetDelegatorInfo is a free data retrieval call binding the contract method 0x53a13338. +// +// Solidity: function getDelegatorInfo(bytes32 delegationID) view returns((uint8,address,bytes32,uint64,uint64,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) GetDelegatorInfo(delegationID [32]byte) (Delegator, error) { + return _NativeTokenStakingManager.Contract.GetDelegatorInfo(&_NativeTokenStakingManager.CallOpts, delegationID) +} + +// GetDelegatorInfo is a free data retrieval call binding the contract method 0x53a13338. +// +// Solidity: function getDelegatorInfo(bytes32 delegationID) view returns((uint8,address,bytes32,uint64,uint64,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) GetDelegatorInfo(delegationID [32]byte) (Delegator, error) { + return _NativeTokenStakingManager.Contract.GetDelegatorInfo(&_NativeTokenStakingManager.CallOpts, delegationID) +} + +// GetDelegatorRewardInfo is a free data retrieval call binding the contract method 0xaf1dd66c. +// +// Solidity: function getDelegatorRewardInfo(bytes32 delegationID) view returns(address, uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) GetDelegatorRewardInfo(opts *bind.CallOpts, delegationID [32]byte) (common.Address, *big.Int, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "getDelegatorRewardInfo", delegationID) + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// GetDelegatorRewardInfo is a free data retrieval call binding the contract method 0xaf1dd66c. +// +// Solidity: function getDelegatorRewardInfo(bytes32 delegationID) view returns(address, uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) GetDelegatorRewardInfo(delegationID [32]byte) (common.Address, *big.Int, error) { + return _NativeTokenStakingManager.Contract.GetDelegatorRewardInfo(&_NativeTokenStakingManager.CallOpts, delegationID) +} + +// GetDelegatorRewardInfo is a free data retrieval call binding the contract method 0xaf1dd66c. +// +// Solidity: function getDelegatorRewardInfo(bytes32 delegationID) view returns(address, uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) GetDelegatorRewardInfo(delegationID [32]byte) (common.Address, *big.Int, error) { + return _NativeTokenStakingManager.Contract.GetDelegatorRewardInfo(&_NativeTokenStakingManager.CallOpts, delegationID) +} + +// GetStakingManagerSettings is a free data retrieval call binding the contract method 0xcaa71874. +// +// Solidity: function getStakingManagerSettings() view returns((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) GetStakingManagerSettings(opts *bind.CallOpts) (StakingManagerSettings, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "getStakingManagerSettings") + + if err != nil { + return *new(StakingManagerSettings), err + } + + out0 := *abi.ConvertType(out[0], new(StakingManagerSettings)).(*StakingManagerSettings) + + return out0, err + +} + +// GetStakingManagerSettings is a free data retrieval call binding the contract method 0xcaa71874. +// +// Solidity: function getStakingManagerSettings() view returns((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) GetStakingManagerSettings() (StakingManagerSettings, error) { + return _NativeTokenStakingManager.Contract.GetStakingManagerSettings(&_NativeTokenStakingManager.CallOpts) +} + +// GetStakingManagerSettings is a free data retrieval call binding the contract method 0xcaa71874. +// +// Solidity: function getStakingManagerSettings() view returns((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) GetStakingManagerSettings() (StakingManagerSettings, error) { + return _NativeTokenStakingManager.Contract.GetStakingManagerSettings(&_NativeTokenStakingManager.CallOpts) +} + +// GetStakingValidator is a free data retrieval call binding the contract method 0x2674874b. +// +// Solidity: function getStakingValidator(bytes32 validationID) view returns((address,uint16,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) GetStakingValidator(opts *bind.CallOpts, validationID [32]byte) (PoSValidatorInfo, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "getStakingValidator", validationID) + + if err != nil { + return *new(PoSValidatorInfo), err + } + + out0 := *abi.ConvertType(out[0], new(PoSValidatorInfo)).(*PoSValidatorInfo) + + return out0, err + +} + +// GetStakingValidator is a free data retrieval call binding the contract method 0x2674874b. +// +// Solidity: function getStakingValidator(bytes32 validationID) view returns((address,uint16,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) GetStakingValidator(validationID [32]byte) (PoSValidatorInfo, error) { + return _NativeTokenStakingManager.Contract.GetStakingValidator(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// GetStakingValidator is a free data retrieval call binding the contract method 0x2674874b. +// +// Solidity: function getStakingValidator(bytes32 validationID) view returns((address,uint16,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) GetStakingValidator(validationID [32]byte) (PoSValidatorInfo, error) { + return _NativeTokenStakingManager.Contract.GetStakingValidator(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// GetValidatorRewardInfo is a free data retrieval call binding the contract method 0xe24b2680. +// +// Solidity: function getValidatorRewardInfo(bytes32 validationID) view returns(address, uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) GetValidatorRewardInfo(opts *bind.CallOpts, validationID [32]byte) (common.Address, *big.Int, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "getValidatorRewardInfo", validationID) + + if err != nil { + return *new(common.Address), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// GetValidatorRewardInfo is a free data retrieval call binding the contract method 0xe24b2680. +// +// Solidity: function getValidatorRewardInfo(bytes32 validationID) view returns(address, uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) GetValidatorRewardInfo(validationID [32]byte) (common.Address, *big.Int, error) { + return _NativeTokenStakingManager.Contract.GetValidatorRewardInfo(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// GetValidatorRewardInfo is a free data retrieval call binding the contract method 0xe24b2680. +// +// Solidity: function getValidatorRewardInfo(bytes32 validationID) view returns(address, uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) GetValidatorRewardInfo(validationID [32]byte) (common.Address, *big.Int, error) { + return _NativeTokenStakingManager.Contract.GetValidatorRewardInfo(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) ValueToWeight(opts *bind.CallOpts, value *big.Int) (uint64, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "valueToWeight", value) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _NativeTokenStakingManager.Contract.ValueToWeight(&_NativeTokenStakingManager.CallOpts, value) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _NativeTokenStakingManager.Contract.ValueToWeight(&_NativeTokenStakingManager.CallOpts, value) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) view returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) WeightToValue(opts *bind.CallOpts, weight uint64) (*big.Int, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "weightToValue", weight) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) view returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _NativeTokenStakingManager.Contract.WeightToValue(&_NativeTokenStakingManager.CallOpts, weight) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) view returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _NativeTokenStakingManager.Contract.WeightToValue(&_NativeTokenStakingManager.CallOpts, weight) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address rewardRecipient) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ChangeDelegatorRewardRecipient(opts *bind.TransactOpts, delegationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "changeDelegatorRewardRecipient", delegationID, rewardRecipient) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address rewardRecipient) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ChangeDelegatorRewardRecipient(delegationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ChangeDelegatorRewardRecipient(&_NativeTokenStakingManager.TransactOpts, delegationID, rewardRecipient) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address rewardRecipient) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ChangeDelegatorRewardRecipient(delegationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ChangeDelegatorRewardRecipient(&_NativeTokenStakingManager.TransactOpts, delegationID, rewardRecipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address rewardRecipient) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ChangeValidatorRewardRecipient(opts *bind.TransactOpts, validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "changeValidatorRewardRecipient", validationID, rewardRecipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address rewardRecipient) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ChangeValidatorRewardRecipient(validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ChangeValidatorRewardRecipient(&_NativeTokenStakingManager.TransactOpts, validationID, rewardRecipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address rewardRecipient) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ChangeValidatorRewardRecipient(validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ChangeValidatorRewardRecipient(&_NativeTokenStakingManager.TransactOpts, validationID, rewardRecipient) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ClaimDelegationFees(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "claimDelegationFees", validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ClaimDelegationFees(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ClaimDelegationFees(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteDelegatorRegistration(opts *bind.TransactOpts, delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeDelegatorRegistration", delegationID, messageIndex) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteDelegatorRegistration(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteDelegatorRegistration(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeDelegatorRemoval", delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteDelegatorRemoval(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteDelegatorRemoval(&_NativeTokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteDelegatorRemoval(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteDelegatorRemoval(&_NativeTokenStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteValidatorRemoval(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeValidatorRemoval", messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRemoval(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRemoval(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ForceInitiateDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "forceInitiateDelegatorRemoval", delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ForceInitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ForceInitiateDelegatorRemoval(&_NativeTokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ForceInitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ForceInitiateDelegatorRemoval(&_NativeTokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ForceInitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "forceInitiateValidatorRemoval", validationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ForceInitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ForceInitiateValidatorRemoval(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ForceInitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ForceInitiateValidatorRemoval(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// Initialize is a paid mutator transaction binding the contract method 0x0d436317. +// +// Solidity: function initialize((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) Initialize(opts *bind.TransactOpts, settings StakingManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initialize", settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x0d436317. +// +// Solidity: function initialize((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) Initialize(settings StakingManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.Initialize(&_NativeTokenStakingManager.TransactOpts, settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x0d436317. +// +// Solidity: function initialize((address,uint256,uint256,uint64,uint16,uint8,uint256,address,bytes32) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) Initialize(settings StakingManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.Initialize(&_NativeTokenStakingManager.TransactOpts, settings) +} + +// InitiateDelegatorRegistration is a paid mutator transaction binding the contract method 0x243ca19a. +// +// Solidity: function initiateDelegatorRegistration(bytes32 validationID, address rewardRecipient) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitiateDelegatorRegistration(opts *bind.TransactOpts, validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initiateDelegatorRegistration", validationID, rewardRecipient) +} + +// InitiateDelegatorRegistration is a paid mutator transaction binding the contract method 0x243ca19a. +// +// Solidity: function initiateDelegatorRegistration(bytes32 validationID, address rewardRecipient) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitiateDelegatorRegistration(validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, validationID, rewardRecipient) +} + +// InitiateDelegatorRegistration is a paid mutator transaction binding the contract method 0x243ca19a. +// +// Solidity: function initiateDelegatorRegistration(bytes32 validationID, address rewardRecipient) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitiateDelegatorRegistration(validationID [32]byte, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, validationID, rewardRecipient) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitiateDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initiateDelegatorRemoval", delegationID, includeUptimeProof, messageIndex) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateDelegatorRemoval(&_NativeTokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateDelegatorRemoval(&_NativeTokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0xad93936d. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitiateValidatorRegistration(opts *bind.TransactOpts, nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, delegationFeeBips uint16, minStakeDuration uint64, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initiateValidatorRegistration", nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDuration, rewardRecipient) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0xad93936d. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, delegationFeeBips uint16, minStakeDuration uint64, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDuration, rewardRecipient) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0xad93936d. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, delegationFeeBips uint16, minStakeDuration uint64, rewardRecipient common.Address) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDuration, rewardRecipient) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initiateValidatorRemoval", validationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateValidatorRemoval(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitiateValidatorRemoval(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ResendUpdateDelegator(opts *bind.TransactOpts, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "resendUpdateDelegator", delegationID) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ResendUpdateDelegator(delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendUpdateDelegator(&_NativeTokenStakingManager.TransactOpts, delegationID) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ResendUpdateDelegator(delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendUpdateDelegator(&_NativeTokenStakingManager.TransactOpts, delegationID) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) SubmitUptimeProof(opts *bind.TransactOpts, validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "submitUptimeProof", validationID, messageIndex) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) SubmitUptimeProof(validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.SubmitUptimeProof(&_NativeTokenStakingManager.TransactOpts, validationID, messageIndex) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) SubmitUptimeProof(validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.SubmitUptimeProof(&_NativeTokenStakingManager.TransactOpts, validationID, messageIndex) +} + +// NativeTokenStakingManagerCompletedDelegatorRegistrationIterator is returned from FilterCompletedDelegatorRegistration and is used to iterate over the raw logs and unpacked data for CompletedDelegatorRegistration events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerCompletedDelegatorRegistrationIterator struct { + Event *NativeTokenStakingManagerCompletedDelegatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerCompletedDelegatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerCompletedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerCompletedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerCompletedDelegatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerCompletedDelegatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerCompletedDelegatorRegistration represents a CompletedDelegatorRegistration event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerCompletedDelegatorRegistration struct { + DelegationID [32]byte + ValidationID [32]byte + StartTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedDelegatorRegistration is a free log retrieval operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterCompletedDelegatorRegistration(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*NativeTokenStakingManagerCompletedDelegatorRegistrationIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "CompletedDelegatorRegistration", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerCompletedDelegatorRegistrationIterator{contract: _NativeTokenStakingManager.contract, event: "CompletedDelegatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchCompletedDelegatorRegistration is a free log subscription operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchCompletedDelegatorRegistration(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerCompletedDelegatorRegistration, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "CompletedDelegatorRegistration", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerCompletedDelegatorRegistration) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRegistration", 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 +} + +// ParseCompletedDelegatorRegistration is a log parse operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseCompletedDelegatorRegistration(log types.Log) (*NativeTokenStakingManagerCompletedDelegatorRegistration, error) { + event := new(NativeTokenStakingManagerCompletedDelegatorRegistration) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerCompletedDelegatorRemovalIterator is returned from FilterCompletedDelegatorRemoval and is used to iterate over the raw logs and unpacked data for CompletedDelegatorRemoval events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerCompletedDelegatorRemovalIterator struct { + Event *NativeTokenStakingManagerCompletedDelegatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerCompletedDelegatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerCompletedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerCompletedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerCompletedDelegatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerCompletedDelegatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerCompletedDelegatorRemoval represents a CompletedDelegatorRemoval event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerCompletedDelegatorRemoval struct { + DelegationID [32]byte + ValidationID [32]byte + Rewards *big.Int + Fees *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedDelegatorRemoval is a free log retrieval operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterCompletedDelegatorRemoval(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*NativeTokenStakingManagerCompletedDelegatorRemovalIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "CompletedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerCompletedDelegatorRemovalIterator{contract: _NativeTokenStakingManager.contract, event: "CompletedDelegatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchCompletedDelegatorRemoval is a free log subscription operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchCompletedDelegatorRemoval(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerCompletedDelegatorRemoval, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "CompletedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerCompletedDelegatorRemoval) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRemoval", 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 +} + +// ParseCompletedDelegatorRemoval is a log parse operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseCompletedDelegatorRemoval(log types.Log) (*NativeTokenStakingManagerCompletedDelegatorRemoval, error) { + event := new(NativeTokenStakingManagerCompletedDelegatorRemoval) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "CompletedDelegatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerDelegatorRewardClaimedIterator is returned from FilterDelegatorRewardClaimed and is used to iterate over the raw logs and unpacked data for DelegatorRewardClaimed events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRewardClaimedIterator struct { + Event *NativeTokenStakingManagerDelegatorRewardClaimed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerDelegatorRewardClaimedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerDelegatorRewardClaimedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerDelegatorRewardClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerDelegatorRewardClaimed represents a DelegatorRewardClaimed event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRewardClaimed struct { + DelegationID [32]byte + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRewardClaimed is a free log retrieval operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterDelegatorRewardClaimed(opts *bind.FilterOpts, delegationID [][32]byte, recipient []common.Address) (*NativeTokenStakingManagerDelegatorRewardClaimedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "DelegatorRewardClaimed", delegationIDRule, recipientRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerDelegatorRewardClaimedIterator{contract: _NativeTokenStakingManager.contract, event: "DelegatorRewardClaimed", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRewardClaimed is a free log subscription operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchDelegatorRewardClaimed(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerDelegatorRewardClaimed, delegationID [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "DelegatorRewardClaimed", delegationIDRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerDelegatorRewardClaimed) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRewardClaimed", 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 +} + +// ParseDelegatorRewardClaimed is a log parse operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseDelegatorRewardClaimed(log types.Log) (*NativeTokenStakingManagerDelegatorRewardClaimed, error) { + event := new(NativeTokenStakingManagerDelegatorRewardClaimed) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRewardClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerDelegatorRewardRecipientChangedIterator is returned from FilterDelegatorRewardRecipientChanged and is used to iterate over the raw logs and unpacked data for DelegatorRewardRecipientChanged events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRewardRecipientChangedIterator struct { + Event *NativeTokenStakingManagerDelegatorRewardRecipientChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerDelegatorRewardRecipientChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerDelegatorRewardRecipientChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerDelegatorRewardRecipientChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerDelegatorRewardRecipientChanged represents a DelegatorRewardRecipientChanged event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRewardRecipientChanged struct { + DelegationID [32]byte + Recipient common.Address + OldRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRewardRecipientChanged is a free log retrieval operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterDelegatorRewardRecipientChanged(opts *bind.FilterOpts, delegationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (*NativeTokenStakingManagerDelegatorRewardRecipientChangedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "DelegatorRewardRecipientChanged", delegationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerDelegatorRewardRecipientChangedIterator{contract: _NativeTokenStakingManager.contract, event: "DelegatorRewardRecipientChanged", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRewardRecipientChanged is a free log subscription operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchDelegatorRewardRecipientChanged(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerDelegatorRewardRecipientChanged, delegationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "DelegatorRewardRecipientChanged", delegationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerDelegatorRewardRecipientChanged) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRewardRecipientChanged", 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 +} + +// ParseDelegatorRewardRecipientChanged is a log parse operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseDelegatorRewardRecipientChanged(log types.Log) (*NativeTokenStakingManagerDelegatorRewardRecipientChanged, error) { + event := new(NativeTokenStakingManagerDelegatorRewardRecipientChanged) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRewardRecipientChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitializedIterator struct { + Event *NativeTokenStakingManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerInitialized represents a Initialized event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*NativeTokenStakingManagerInitializedIterator, error) { + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerInitializedIterator{contract: _NativeTokenStakingManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseInitialized(log types.Log) (*NativeTokenStakingManagerInitialized, error) { + event := new(NativeTokenStakingManagerInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerInitiatedDelegatorRegistrationIterator is returned from FilterInitiatedDelegatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedDelegatorRegistration events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitiatedDelegatorRegistrationIterator struct { + Event *NativeTokenStakingManagerInitiatedDelegatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerInitiatedDelegatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitiatedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitiatedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerInitiatedDelegatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerInitiatedDelegatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerInitiatedDelegatorRegistration represents a InitiatedDelegatorRegistration event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitiatedDelegatorRegistration struct { + DelegationID [32]byte + ValidationID [32]byte + DelegatorAddress common.Address + Nonce uint64 + ValidatorWeight uint64 + DelegatorWeight uint64 + SetWeightMessageID [32]byte + RewardRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedDelegatorRegistration is a free log retrieval operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterInitiatedDelegatorRegistration(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (*NativeTokenStakingManagerInitiatedDelegatorRegistrationIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "InitiatedDelegatorRegistration", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerInitiatedDelegatorRegistrationIterator{contract: _NativeTokenStakingManager.contract, event: "InitiatedDelegatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedDelegatorRegistration is a free log subscription operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchInitiatedDelegatorRegistration(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerInitiatedDelegatorRegistration, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "InitiatedDelegatorRegistration", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerInitiatedDelegatorRegistration) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRegistration", 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 +} + +// ParseInitiatedDelegatorRegistration is a log parse operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseInitiatedDelegatorRegistration(log types.Log) (*NativeTokenStakingManagerInitiatedDelegatorRegistration, error) { + event := new(NativeTokenStakingManagerInitiatedDelegatorRegistration) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerInitiatedDelegatorRemovalIterator is returned from FilterInitiatedDelegatorRemoval and is used to iterate over the raw logs and unpacked data for InitiatedDelegatorRemoval events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitiatedDelegatorRemovalIterator struct { + Event *NativeTokenStakingManagerInitiatedDelegatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerInitiatedDelegatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitiatedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitiatedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerInitiatedDelegatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerInitiatedDelegatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerInitiatedDelegatorRemoval represents a InitiatedDelegatorRemoval event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitiatedDelegatorRemoval struct { + DelegationID [32]byte + ValidationID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedDelegatorRemoval is a free log retrieval operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterInitiatedDelegatorRemoval(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*NativeTokenStakingManagerInitiatedDelegatorRemovalIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "InitiatedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerInitiatedDelegatorRemovalIterator{contract: _NativeTokenStakingManager.contract, event: "InitiatedDelegatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchInitiatedDelegatorRemoval is a free log subscription operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchInitiatedDelegatorRemoval(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerInitiatedDelegatorRemoval, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "InitiatedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerInitiatedDelegatorRemoval) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRemoval", 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 +} + +// ParseInitiatedDelegatorRemoval is a log parse operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseInitiatedDelegatorRemoval(log types.Log) (*NativeTokenStakingManagerInitiatedDelegatorRemoval, error) { + event := new(NativeTokenStakingManagerInitiatedDelegatorRemoval) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerInitiatedStakingValidatorRegistrationIterator is returned from FilterInitiatedStakingValidatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedStakingValidatorRegistration events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitiatedStakingValidatorRegistrationIterator struct { + Event *NativeTokenStakingManagerInitiatedStakingValidatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerInitiatedStakingValidatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitiatedStakingValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitiatedStakingValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerInitiatedStakingValidatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerInitiatedStakingValidatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerInitiatedStakingValidatorRegistration represents a InitiatedStakingValidatorRegistration event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitiatedStakingValidatorRegistration struct { + ValidationID [32]byte + Owner common.Address + DelegationFeeBips uint16 + MinStakeDuration uint64 + RewardRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedStakingValidatorRegistration is a free log retrieval operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterInitiatedStakingValidatorRegistration(opts *bind.FilterOpts, validationID [][32]byte, owner []common.Address) (*NativeTokenStakingManagerInitiatedStakingValidatorRegistrationIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "InitiatedStakingValidatorRegistration", validationIDRule, ownerRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerInitiatedStakingValidatorRegistrationIterator{contract: _NativeTokenStakingManager.contract, event: "InitiatedStakingValidatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedStakingValidatorRegistration is a free log subscription operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchInitiatedStakingValidatorRegistration(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerInitiatedStakingValidatorRegistration, validationID [][32]byte, owner []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "InitiatedStakingValidatorRegistration", validationIDRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerInitiatedStakingValidatorRegistration) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitiatedStakingValidatorRegistration", 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 +} + +// ParseInitiatedStakingValidatorRegistration is a log parse operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseInitiatedStakingValidatorRegistration(log types.Log) (*NativeTokenStakingManagerInitiatedStakingValidatorRegistration, error) { + event := new(NativeTokenStakingManagerInitiatedStakingValidatorRegistration) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitiatedStakingValidatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerUptimeUpdatedIterator is returned from FilterUptimeUpdated and is used to iterate over the raw logs and unpacked data for UptimeUpdated events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerUptimeUpdatedIterator struct { + Event *NativeTokenStakingManagerUptimeUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerUptimeUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerUptimeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerUptimeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerUptimeUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerUptimeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerUptimeUpdated represents a UptimeUpdated event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerUptimeUpdated struct { + ValidationID [32]byte + Uptime uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUptimeUpdated is a free log retrieval operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterUptimeUpdated(opts *bind.FilterOpts, validationID [][32]byte) (*NativeTokenStakingManagerUptimeUpdatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "UptimeUpdated", validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerUptimeUpdatedIterator{contract: _NativeTokenStakingManager.contract, event: "UptimeUpdated", logs: logs, sub: sub}, nil +} + +// WatchUptimeUpdated is a free log subscription operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchUptimeUpdated(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerUptimeUpdated, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "UptimeUpdated", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerUptimeUpdated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "UptimeUpdated", 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 +} + +// ParseUptimeUpdated is a log parse operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseUptimeUpdated(log types.Log) (*NativeTokenStakingManagerUptimeUpdated, error) { + event := new(NativeTokenStakingManagerUptimeUpdated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "UptimeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidatorRewardClaimedIterator is returned from FilterValidatorRewardClaimed and is used to iterate over the raw logs and unpacked data for ValidatorRewardClaimed events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRewardClaimedIterator struct { + Event *NativeTokenStakingManagerValidatorRewardClaimed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidatorRewardClaimedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidatorRewardClaimedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidatorRewardClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidatorRewardClaimed represents a ValidatorRewardClaimed event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRewardClaimed struct { + ValidationID [32]byte + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRewardClaimed is a free log retrieval operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidatorRewardClaimed(opts *bind.FilterOpts, validationID [][32]byte, recipient []common.Address) (*NativeTokenStakingManagerValidatorRewardClaimedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidatorRewardClaimed", validationIDRule, recipientRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidatorRewardClaimedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidatorRewardClaimed", logs: logs, sub: sub}, nil +} + +// WatchValidatorRewardClaimed is a free log subscription operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidatorRewardClaimed(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidatorRewardClaimed, validationID [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidatorRewardClaimed", validationIDRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidatorRewardClaimed) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRewardClaimed", 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 +} + +// ParseValidatorRewardClaimed is a log parse operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidatorRewardClaimed(log types.Log) (*NativeTokenStakingManagerValidatorRewardClaimed, error) { + event := new(NativeTokenStakingManagerValidatorRewardClaimed) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRewardClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidatorRewardRecipientChangedIterator is returned from FilterValidatorRewardRecipientChanged and is used to iterate over the raw logs and unpacked data for ValidatorRewardRecipientChanged events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRewardRecipientChangedIterator struct { + Event *NativeTokenStakingManagerValidatorRewardRecipientChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidatorRewardRecipientChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidatorRewardRecipientChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidatorRewardRecipientChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidatorRewardRecipientChanged represents a ValidatorRewardRecipientChanged event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRewardRecipientChanged struct { + ValidationID [32]byte + Recipient common.Address + OldRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRewardRecipientChanged is a free log retrieval operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidatorRewardRecipientChanged(opts *bind.FilterOpts, validationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (*NativeTokenStakingManagerValidatorRewardRecipientChangedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidatorRewardRecipientChanged", validationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidatorRewardRecipientChangedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidatorRewardRecipientChanged", logs: logs, sub: sub}, nil +} + +// WatchValidatorRewardRecipientChanged is a free log subscription operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidatorRewardRecipientChanged(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidatorRewardRecipientChanged, validationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidatorRewardRecipientChanged", validationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidatorRewardRecipientChanged) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRewardRecipientChanged", 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 +} + +// ParseValidatorRewardRecipientChanged is a log parse operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidatorRewardRecipientChanged(log types.Log) (*NativeTokenStakingManagerValidatorRewardRecipientChanged, error) { + event := new(NativeTokenStakingManagerValidatorRewardRecipientChanged) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRewardRecipientChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorMessagesMetaData contains all meta data concerning the ValidatorMessages contract. +var ValidatorMessagesMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"InvalidBLSPublicKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"InvalidCodecID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"actual\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageType\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"validatorManagerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structInitialValidator[]\",\"name\":\"initialValidators\",\"type\":\"tuple[]\"}],\"internalType\":\"structConversionData\",\"name\":\"conversionData\",\"type\":\"tuple\"}],\"name\":\"packConversionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"}],\"name\":\"packL1ValidatorRegistrationMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"packL1ValidatorWeightMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structValidatorMessages.ValidationPeriod\",\"name\":\"validationPeriod\",\"type\":\"tuple\"}],\"name\":\"packRegisterL1ValidatorMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"conversionID\",\"type\":\"bytes32\"}],\"name\":\"packSubnetToL1ConversionMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"uptime\",\"type\":\"uint64\"}],\"name\":\"packValidationUptimeMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackL1ValidatorRegistrationMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackL1ValidatorWeightMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackRegisterL1ValidatorMessage\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structValidatorMessages.ValidationPeriod\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackSubnetToL1ConversionMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackValidationUptimeMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x61217b610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100b1575f3560e01c8063854a893f11610079578063854a893f146101b257806387418b8e1461020f5780639b83546514610222578063a699c13514610242578063e1d68f3014610255578063eb97ce5114610268575f80fd5b8063021de88f146100b5578063088c2463146100e25780634d8478841461011257806350782b0f146101335780637f7c427a1461016b575b5f80fd5b6100c86100c33660046118a9565b610289565b604080519283529015156020830152015b60405180910390f35b6100f56100f03660046118a9565b61044a565b604080519283526001600160401b039091166020830152016100d9565b6101256101203660046118a9565b61063b565b6040519081526020016100d9565b6101466101413660046118a9565b6107c8565b604080519384526001600160401b0392831660208501529116908201526060016100d9565b6101a56101793660046118e2565b604080515f60208201819052602282015260268082019390935281518082039093018352604601905290565b6040516100d99190611946565b6101a56101c036600461197a565b604080515f6020820152600360e01b602282015260268101949094526001600160c01b031960c093841b811660468601529190921b16604e830152805180830360360181526056909201905290565b6101a561021d3660046119eb565b610a1e565b6102356102303660046118a9565b610b60565b6040516100d99190611bb4565b6101a5610250366004611c6b565b6114ab565b6101a5610263366004611c9d565b6114ef565b61027b610276366004611d80565b611525565b6040516100d9929190611e7c565b5f8082516027146102c457825160405163cc92daa160e01b815263ffffffff9091166004820152602760248201526044015b60405180910390fd5b5f805b6002811015610313576102db816001611ea8565b6102e6906008611ebb565b61ffff168582815181106102fc576102fc611ed2565b016020015160f81c901b91909117906001016102c7565b5061ffff81161561033d5760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561039857610354816003611ea8565b61035f906008611ebb565b63ffffffff1686610371836002611ee6565b8151811061038157610381611ed2565b016020015160f81c901b9190911790600101610340565b5063ffffffff81166002146103c057604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015610415576103d781601f611ea8565b6103e2906008611ebb565b876103ee836006611ee6565b815181106103fe576103fe611ed2565b016020015160f81c901b91909117906001016103c3565b505f8660268151811061042a5761042a611ed2565b016020015191976001600160f81b03199092161515965090945050505050565b5f808251602e1461048057825160405163cc92daa160e01b815263ffffffff9091166004820152602e60248201526044016102bb565b5f805b60028110156104cf57610497816001611ea8565b6104a2906008611ebb565b61ffff168582815181106104b8576104b8611ed2565b016020015160f81c901b9190911790600101610483565b5061ffff8116156104f95760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561055457610510816003611ea8565b61051b906008611ebb565b63ffffffff168661052d836002611ee6565b8151811061053d5761053d611ed2565b016020015160f81c901b91909117906001016104fc565b5063ffffffff81161561057a57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156105cf5761059181601f611ea8565b61059c906008611ebb565b876105a8836006611ee6565b815181106105b8576105b8611ed2565b016020015160f81c901b919091179060010161057d565b505f805b600881101561062e576105e7816007611ea8565b6105f2906008611ebb565b6001600160401b031688610607836026611ee6565b8151811061061757610617611ed2565b016020015160f81c901b91909117906001016105d3565b5090969095509350505050565b5f815160261461067057815160405163cc92daa160e01b815263ffffffff9091166004820152602660248201526044016102bb565b5f805b60028110156106bf57610687816001611ea8565b610692906008611ebb565b61ffff168482815181106106a8576106a8611ed2565b016020015160f81c901b9190911790600101610673565b5061ffff8116156106e95760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561074457610700816003611ea8565b61070b906008611ebb565b63ffffffff168561071d836002611ee6565b8151811061072d5761072d611ed2565b016020015160f81c901b91909117906001016106ec565b5063ffffffff81161561076a57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156107bf5761078181601f611ea8565b61078c906008611ebb565b86610798836006611ee6565b815181106107a8576107a8611ed2565b016020015160f81c901b919091179060010161076d565b50949350505050565b5f805f83516036146107ff57835160405163cc92daa160e01b815263ffffffff9091166004820152603660248201526044016102bb565b5f805b600281101561084e57610816816001611ea8565b610821906008611ebb565b61ffff1686828151811061083757610837611ed2565b016020015160f81c901b9190911790600101610802565b5061ffff8116156108785760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b60048110156108d35761088f816003611ea8565b61089a906008611ebb565b63ffffffff16876108ac836002611ee6565b815181106108bc576108bc611ed2565b016020015160f81c901b919091179060010161087b565b5063ffffffff81166003146108fb57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156109505761091281601f611ea8565b61091d906008611ebb565b88610929836006611ee6565b8151811061093957610939611ed2565b016020015160f81c901b91909117906001016108fe565b505f805b60088110156109af57610968816007611ea8565b610973906008611ebb565b6001600160401b031689610988836026611ee6565b8151811061099857610998611ed2565b016020015160f81c901b9190911790600101610954565b505f805b6008811015610a0e576109c7816007611ea8565b6109d2906008611ebb565b6001600160401b03168a6109e783602e611ee6565b815181106109f7576109f7611ed2565b016020015160f81c901b91909117906001016109b3565b5091989097509095509350505050565b80516020808301516040808501516060868101515192515f95810186905260228101969096526042860193909352600560e21b60628601526bffffffffffffffffffffffff1990831b16606685015260e01b6001600160e01b031916607a84015291607e0160405160208183030381529060405290505f5b836060015151811015610b59578184606001518281518110610aba57610aba611ed2565b60200260200101515f01515185606001518381518110610adc57610adc611ed2565b60200260200101515f015186606001518481518110610afd57610afd611ed2565b60200260200101516020015187606001518581518110610b1f57610b1f611ed2565b602002602001015160400151604051602001610b3f959493929190611ef9565b60408051601f198184030181529190529150600101610a96565b5092915050565b610b68611712565b5f610b71611712565b5f805b6002811015610bcf57610b88816001611ea8565b610b93906008611ebb565b61ffff1686610ba863ffffffff871684611ee6565b81518110610bb857610bb8611ed2565b016020015160f81c901b9190911790600101610b74565b5061ffff811615610bf95760405163407b587360e01b815261ffff821660048201526024016102bb565b610c04600284611f72565b9250505f805b6004811015610c6957610c1e816003611ea8565b610c29906008611ebb565b63ffffffff16868563ffffffff1683610c429190611ee6565b81518110610c5257610c52611ed2565b016020015160f81c901b9190911790600101610c0a565b5063ffffffff8116600114610c9157604051635b60892f60e01b815260040160405180910390fd5b610c9c600484611f72565b9250505f805b6020811015610cf957610cb681601f611ea8565b610cc1906008611ebb565b86610cd263ffffffff871684611ee6565b81518110610ce257610ce2611ed2565b016020015160f81c901b9190911790600101610ca2565b50808252610d08602084611f72565b9250505f805b6004811015610d6d57610d22816003611ea8565b610d2d906008611ebb565b63ffffffff16868563ffffffff1683610d469190611ee6565b81518110610d5657610d56611ed2565b016020015160f81c901b9190911790600101610d0e565b50610d79600484611f72565b92505f8163ffffffff166001600160401b03811115610d9a57610d9a61176c565b6040519080825280601f01601f191660200182016040528015610dc4576020820181803683370190505b5090505f5b8263ffffffff16811015610e335786610de863ffffffff871683611ee6565b81518110610df857610df8611ed2565b602001015160f81c60f81b828281518110610e1557610e15611ed2565b60200101906001600160f81b03191690815f1a905350600101610dc9565b5060208301819052610e458285611f72565b604080516030808252606082019092529195505f92506020820181803683370190505090505f5b6030811015610ed15786610e8663ffffffff871683611ee6565b81518110610e9657610e96611ed2565b602001015160f81c60f81b828281518110610eb357610eb3611ed2565b60200101906001600160f81b03191690815f1a905350600101610e6c565b5060408301819052610ee4603085611f72565b9350505f805b6008811015610f4a57610efe816007611ea8565b610f09906008611ebb565b6001600160401b031687610f2363ffffffff881684611ee6565b81518110610f3357610f33611ed2565b016020015160f81c901b9190911790600101610eea565b506001600160401b0381166060840152610f65600885611f72565b9350505f805f5b6004811015610fcb57610f80816003611ea8565b610f8b906008611ebb565b63ffffffff16888763ffffffff1683610fa49190611ee6565b81518110610fb457610fb4611ed2565b016020015160f81c901b9190911790600101610f6c565b50610fd7600486611f72565b94505f5b600481101561103a57610fef816003611ea8565b610ffa906008611ebb565b63ffffffff16888763ffffffff16836110139190611ee6565b8151811061102357611023611ed2565b016020015160f81c901b9290921791600101610fdb565b50611046600486611f72565b94505f8263ffffffff166001600160401b038111156110675761106761176c565b604051908082528060200260200182016040528015611090578160200160208202803683370190505b5090505f5b8363ffffffff16811015611178576040805160148082528183019092525f916020820181803683370190505090505f5b601481101561112a578a6110df63ffffffff8b1683611ee6565b815181106110ef576110ef611ed2565b602001015160f81c60f81b82828151811061110c5761110c611ed2565b60200101906001600160f81b03191690815f1a9053506001016110c5565b505f601482015190508084848151811061114657611146611ed2565b6001600160a01b039092166020928302919091019091015261116960148a611f72565b98505050806001019050611095565b506040805180820190915263ffffffff9092168252602082015260808401525f80805b60048110156111fa576111af816003611ea8565b6111ba906008611ebb565b63ffffffff16898863ffffffff16836111d39190611ee6565b815181106111e3576111e3611ed2565b016020015160f81c901b919091179060010161119b565b50611206600487611f72565b95505f5b60048110156112695761121e816003611ea8565b611229906008611ebb565b63ffffffff16898863ffffffff16836112429190611ee6565b8151811061125257611252611ed2565b016020015160f81c901b929092179160010161120a565b50611275600487611f72565b95505f8263ffffffff166001600160401b038111156112965761129661176c565b6040519080825280602002602001820160405280156112bf578160200160208202803683370190505b5090505f5b8363ffffffff168110156113a7576040805160148082528183019092525f916020820181803683370190505090505f5b6014811015611359578b61130e63ffffffff8c1683611ee6565b8151811061131e5761131e611ed2565b602001015160f81c60f81b82828151811061133b5761133b611ed2565b60200101906001600160f81b03191690815f1a9053506001016112f4565b505f601482015190508084848151811061137557611375611ed2565b6001600160a01b039092166020928302919091019091015261139860148b611f72565b995050508060010190506112c4565b506040805180820190915263ffffffff9092168252602082015260a08501525f6113d18284611f72565b6113dc906014611f8f565b6113e785607a611f72565b6113f19190611f72565b90508063ffffffff1688511461142d57875160405163cc92daa160e01b815263ffffffff918216600482015290821660248201526044016102bb565b5f805b600881101561149057611444816007611ea8565b61144f906008611ebb565b6001600160401b03168a61146963ffffffff8b1684611ee6565b8151811061147957611479611ed2565b016020015160f81c901b9190911790600101611430565b506001600160401b031660c086015250929695505050505050565b6040515f6020820152600160e11b60228201526026810183905281151560f81b60468201526060906047015b60405160208183030381529060405290505b92915050565b6040515f602082018190526022820152602681018390526001600160c01b031960c083901b166046820152606090604e016114d7565b5f606082604001515160301461154e5760405163180ffa0d60e01b815260040160405180910390fd5b82516020808501518051604080880151606089015160808a01518051908701515193515f9861158f988a986001989297929690959094909390929101611fb7565b60405160208183030381529060405290505f5b84608001516020015151811015611601578185608001516020015182815181106115ce576115ce611ed2565b60200260200101516040516020016115e7929190612071565b60408051601f1981840301815291905291506001016115a2565b5060a08401518051602091820151516040516116219385939291016120a7565b60405160208183030381529060405290505f5b8460a00151602001515181101561169357818560a0015160200151828151811061166057611660611ed2565b6020026020010151604051602001611679929190612071565b60408051601f198184030181529190529150600101611634565b5060c08401516040516116aa9183916020016120e2565b60405160208183030381529060405290506002816040516116cb9190612113565b602060405180830381855afa1580156116e6573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611709919061212e565b94909350915050565b6040805160e0810182525f808252606060208084018290528385018290528184018390528451808601865283815280820183905260808501528451808601909552918452908301529060a082019081525f60209091015290565b634e487b7160e01b5f52604160045260245ffd5b604051608081016001600160401b03811182821017156117a2576117a261176c565b60405290565b604051606081016001600160401b03811182821017156117a2576117a261176c565b604080519081016001600160401b03811182821017156117a2576117a261176c565b60405160e081016001600160401b03811182821017156117a2576117a261176c565b604051601f8201601f191681016001600160401b03811182821017156118365761183661176c565b604052919050565b5f82601f83011261184d575f80fd5b81356001600160401b038111156118665761186661176c565b611879601f8201601f191660200161180e565b81815284602083860101111561188d575f80fd5b816020850160208301375f918101602001919091529392505050565b5f602082840312156118b9575f80fd5b81356001600160401b038111156118ce575f80fd5b6118da8482850161183e565b949350505050565b5f602082840312156118f2575f80fd5b5035919050565b5f5b838110156119135781810151838201526020016118fb565b50505f910152565b5f81518084526119328160208601602086016118f9565b601f01601f19169290920160200192915050565b602081525f611958602083018461191b565b9392505050565b80356001600160401b0381168114611975575f80fd5b919050565b5f805f6060848603121561198c575f80fd5b8335925061199c6020850161195f565b91506119aa6040850161195f565b90509250925092565b80356001600160a01b0381168114611975575f80fd5b5f6001600160401b038211156119e1576119e161176c565b5060051b60200190565b5f60208083850312156119fc575f80fd5b82356001600160401b0380821115611a12575f80fd5b9084019060808287031215611a25575f80fd5b611a2d611780565b823581528383013584820152611a45604084016119b3565b604082015260608084013583811115611a5c575f80fd5b80850194505087601f850112611a70575f80fd5b8335611a83611a7e826119c9565b61180e565b81815260059190911b8501860190868101908a831115611aa1575f80fd5b8787015b83811015611b3a57803587811115611abb575f80fd5b8801808d03601f1901861315611acf575f80fd5b611ad76117a8565b8a82013589811115611ae7575f80fd5b611af58f8d8386010161183e565b825250604082013589811115611b09575f80fd5b611b178f8d8386010161183e565b8c83015250611b2787830161195f565b6040820152845250918801918801611aa5565b506060850152509198975050505050505050565b5f6040830163ffffffff8351168452602080840151604060208701528281518085526060880191506020830194505f92505b80831015611ba95784516001600160a01b03168252938301936001929092019190830190611b80565b509695505050505050565b60208152815160208201525f602083015160e06040840152611bda61010084018261191b565b90506040840151601f1980858403016060860152611bf8838361191b565b92506001600160401b03606087015116608086015260808601519150808584030160a0860152611c288383611b4e565b925060a08601519150808584030160c086015250611c468282611b4e565b91505060c0840151611c6360e08501826001600160401b03169052565b509392505050565b5f8060408385031215611c7c575f80fd5b8235915060208301358015158114611c92575f80fd5b809150509250929050565b5f8060408385031215611cae575f80fd5b82359150611cbe6020840161195f565b90509250929050565b5f60408284031215611cd7575f80fd5b611cdf6117ca565b9050813563ffffffff81168114611cf4575f80fd5b81526020828101356001600160401b03811115611d0f575f80fd5b8301601f81018513611d1f575f80fd5b8035611d2d611a7e826119c9565b81815260059190911b82018301908381019087831115611d4b575f80fd5b928401925b82841015611d7057611d61846119b3565b82529284019290840190611d50565b8085870152505050505092915050565b5f60208284031215611d90575f80fd5b81356001600160401b0380821115611da6575f80fd5b9083019060e08286031215611db9575f80fd5b611dc16117ec565b82358152602083013582811115611dd6575f80fd5b611de28782860161183e565b602083015250604083013582811115611df9575f80fd5b611e058782860161183e565b604083015250611e176060840161195f565b6060820152608083013582811115611e2d575f80fd5b611e3987828601611cc7565b60808301525060a083013582811115611e50575f80fd5b611e5c87828601611cc7565b60a083015250611e6e60c0840161195f565b60c082015295945050505050565b828152604060208201525f6118da604083018461191b565b634e487b7160e01b5f52601160045260245ffd5b818103818111156114e9576114e9611e94565b80820281158282048414176114e9576114e9611e94565b634e487b7160e01b5f52603260045260245ffd5b808201808211156114e9576114e9611e94565b5f8651611f0a818460208b016118f9565b60e087901b6001600160e01b0319169083019081528551611f32816004840160208a016118f9565b8551910190611f488160048401602089016118f9565b60c09490941b6001600160c01b031916600491909401908101939093525050600c01949350505050565b63ffffffff818116838216019080821115610b5957610b59611e94565b63ffffffff818116838216028082169190828114611faf57611faf611e94565b505092915050565b61ffff60f01b8a60f01b1681525f63ffffffff60e01b808b60e01b166002840152896006840152808960e01b166026840152508651611ffd81602a850160208b016118f9565b86519083019061201481602a840160208b016118f9565b60c087901b6001600160c01b031916602a9290910191820152612046603282018660e01b6001600160e01b0319169052565b61205f603682018560e01b6001600160e01b0319169052565b603a019b9a5050505050505050505050565b5f83516120828184602088016118f9565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b5f84516120b88184602089016118f9565b6001600160e01b031960e095861b8116919093019081529290931b16600482015260080192915050565b5f83516120f38184602088016118f9565b60c09390931b6001600160c01b0319169190920190815260080192915050565b5f82516121248184602087016118f9565b9190910192915050565b5f6020828403121561213e575f80fd5b505191905056fea26469706673582212204c79a1f4a6f5c66db9481c372405f40b1b5d511151053a9518bb9ce8f1032e4164736f6c63430008190033", +} + +// ValidatorMessagesABI is the input ABI used to generate the binding from. +// Deprecated: Use ValidatorMessagesMetaData.ABI instead. +var ValidatorMessagesABI = ValidatorMessagesMetaData.ABI + +// ValidatorMessagesBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ValidatorMessagesMetaData.Bin instead. +var ValidatorMessagesBin = ValidatorMessagesMetaData.Bin + +// DeployValidatorMessages deploys a new Ethereum contract, binding an instance of ValidatorMessages to it. +func DeployValidatorMessages(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ValidatorMessages, error) { + parsed, err := ValidatorMessagesMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ValidatorMessagesBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ValidatorMessages{ValidatorMessagesCaller: ValidatorMessagesCaller{contract: contract}, ValidatorMessagesTransactor: ValidatorMessagesTransactor{contract: contract}, ValidatorMessagesFilterer: ValidatorMessagesFilterer{contract: contract}}, nil +} + +// ValidatorMessages is an auto generated Go binding around an Ethereum contract. +type ValidatorMessages struct { + ValidatorMessagesCaller // Read-only binding to the contract + ValidatorMessagesTransactor // Write-only binding to the contract + ValidatorMessagesFilterer // Log filterer for contract events +} + +// ValidatorMessagesCaller is an auto generated read-only Go binding around an Ethereum contract. +type ValidatorMessagesCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ValidatorMessagesTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ValidatorMessagesFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ValidatorMessagesSession struct { + Contract *ValidatorMessages // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorMessagesCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ValidatorMessagesCallerSession struct { + Contract *ValidatorMessagesCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ValidatorMessagesTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ValidatorMessagesTransactorSession struct { + Contract *ValidatorMessagesTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorMessagesRaw is an auto generated low-level Go binding around an Ethereum contract. +type ValidatorMessagesRaw struct { + Contract *ValidatorMessages // Generic contract binding to access the raw methods on +} + +// ValidatorMessagesCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ValidatorMessagesCallerRaw struct { + Contract *ValidatorMessagesCaller // Generic read-only contract binding to access the raw methods on +} + +// ValidatorMessagesTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ValidatorMessagesTransactorRaw struct { + Contract *ValidatorMessagesTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewValidatorMessages creates a new instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessages(address common.Address, backend bind.ContractBackend) (*ValidatorMessages, error) { + contract, err := bindValidatorMessages(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ValidatorMessages{ValidatorMessagesCaller: ValidatorMessagesCaller{contract: contract}, ValidatorMessagesTransactor: ValidatorMessagesTransactor{contract: contract}, ValidatorMessagesFilterer: ValidatorMessagesFilterer{contract: contract}}, nil +} + +// NewValidatorMessagesCaller creates a new read-only instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesCaller(address common.Address, caller bind.ContractCaller) (*ValidatorMessagesCaller, error) { + contract, err := bindValidatorMessages(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ValidatorMessagesCaller{contract: contract}, nil +} + +// NewValidatorMessagesTransactor creates a new write-only instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorMessagesTransactor, error) { + contract, err := bindValidatorMessages(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ValidatorMessagesTransactor{contract: contract}, nil +} + +// NewValidatorMessagesFilterer creates a new log filterer instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorMessagesFilterer, error) { + contract, err := bindValidatorMessages(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ValidatorMessagesFilterer{contract: contract}, nil +} + +// bindValidatorMessages binds a generic wrapper to an already deployed contract. +func bindValidatorMessages(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ValidatorMessagesMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorMessages *ValidatorMessagesRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorMessages.Contract.ValidatorMessagesCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorMessages *ValidatorMessagesRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorMessages.Contract.ValidatorMessagesTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorMessages *ValidatorMessagesRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorMessages.Contract.ValidatorMessagesTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorMessages *ValidatorMessagesCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorMessages.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorMessages *ValidatorMessagesTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorMessages.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorMessages *ValidatorMessagesTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorMessages.Contract.contract.Transact(opts, method, params...) +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackConversionData(opts *bind.CallOpts, conversionData ConversionData) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packConversionData", conversionData) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackConversionData(conversionData ConversionData) ([]byte, error) { + return _ValidatorMessages.Contract.PackConversionData(&_ValidatorMessages.CallOpts, conversionData) +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackConversionData(conversionData ConversionData) ([]byte, error) { + return _ValidatorMessages.Contract.PackConversionData(&_ValidatorMessages.CallOpts, conversionData) +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackL1ValidatorRegistrationMessage(opts *bind.CallOpts, validationID [32]byte, registered bool) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packL1ValidatorRegistrationMessage", validationID, registered) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackL1ValidatorRegistrationMessage(validationID [32]byte, registered bool) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, validationID, registered) +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackL1ValidatorRegistrationMessage(validationID [32]byte, registered bool) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, validationID, registered) +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackL1ValidatorWeightMessage(opts *bind.CallOpts, validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packL1ValidatorWeightMessage", validationID, nonce, weight) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackL1ValidatorWeightMessage(validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, validationID, nonce, weight) +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackL1ValidatorWeightMessage(validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, validationID, nonce, weight) +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackRegisterL1ValidatorMessage(opts *bind.CallOpts, validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packRegisterL1ValidatorMessage", validationPeriod) + + if err != nil { + return *new([32]byte), *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte) + + return out0, out1, err + +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackRegisterL1ValidatorMessage(validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + return _ValidatorMessages.Contract.PackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, validationPeriod) +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackRegisterL1ValidatorMessage(validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + return _ValidatorMessages.Contract.PackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, validationPeriod) +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackSubnetToL1ConversionMessage(opts *bind.CallOpts, conversionID [32]byte) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packSubnetToL1ConversionMessage", conversionID) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackSubnetToL1ConversionMessage(conversionID [32]byte) ([]byte, error) { + return _ValidatorMessages.Contract.PackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, conversionID) +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackSubnetToL1ConversionMessage(conversionID [32]byte) ([]byte, error) { + return _ValidatorMessages.Contract.PackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, conversionID) +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackValidationUptimeMessage(opts *bind.CallOpts, validationID [32]byte, uptime uint64) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packValidationUptimeMessage", validationID, uptime) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackValidationUptimeMessage(validationID [32]byte, uptime uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackValidationUptimeMessage(&_ValidatorMessages.CallOpts, validationID, uptime) +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackValidationUptimeMessage(validationID [32]byte, uptime uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackValidationUptimeMessage(&_ValidatorMessages.CallOpts, validationID, uptime) +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackL1ValidatorRegistrationMessage(opts *bind.CallOpts, input []byte) ([32]byte, bool, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackL1ValidatorRegistrationMessage", input) + + if err != nil { + return *new([32]byte), *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(bool)).(*bool) + + return out0, out1, err + +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackL1ValidatorRegistrationMessage(input []byte) ([32]byte, bool, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackL1ValidatorRegistrationMessage(input []byte) ([32]byte, bool, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackL1ValidatorWeightMessage(opts *bind.CallOpts, input []byte) ([32]byte, uint64, uint64, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackL1ValidatorWeightMessage", input) + + if err != nil { + return *new([32]byte), *new(uint64), *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(uint64)).(*uint64) + out2 := *abi.ConvertType(out[2], new(uint64)).(*uint64) + + return out0, out1, out2, err + +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackL1ValidatorWeightMessage(input []byte) ([32]byte, uint64, uint64, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackL1ValidatorWeightMessage(input []byte) ([32]byte, uint64, uint64, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackRegisterL1ValidatorMessage(opts *bind.CallOpts, input []byte) (ValidatorMessagesValidationPeriod, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackRegisterL1ValidatorMessage", input) + + if err != nil { + return *new(ValidatorMessagesValidationPeriod), err + } + + out0 := *abi.ConvertType(out[0], new(ValidatorMessagesValidationPeriod)).(*ValidatorMessagesValidationPeriod) + + return out0, err + +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackRegisterL1ValidatorMessage(input []byte) (ValidatorMessagesValidationPeriod, error) { + return _ValidatorMessages.Contract.UnpackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackRegisterL1ValidatorMessage(input []byte) (ValidatorMessagesValidationPeriod, error) { + return _ValidatorMessages.Contract.UnpackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackSubnetToL1ConversionMessage(opts *bind.CallOpts, input []byte) ([32]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackSubnetToL1ConversionMessage", input) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackSubnetToL1ConversionMessage(input []byte) ([32]byte, error) { + return _ValidatorMessages.Contract.UnpackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackSubnetToL1ConversionMessage(input []byte) ([32]byte, error) { + return _ValidatorMessages.Contract.UnpackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackValidationUptimeMessage(opts *bind.CallOpts, input []byte) ([32]byte, uint64, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackValidationUptimeMessage", input) + + if err != nil { + return *new([32]byte), *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return out0, out1, err + +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackValidationUptimeMessage(input []byte) ([32]byte, uint64, error) { + return _ValidatorMessages.Contract.UnpackValidationUptimeMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackValidationUptimeMessage(input []byte) ([32]byte, uint64, error) { + return _ValidatorMessages.Contract.UnpackValidationUptimeMessage(&_ValidatorMessages.CallOpts, input) +} diff --git a/abi-bindings/go/validator-manager/PoAManager/PoAManager.go b/abi-bindings/go/validator-manager/PoAManager/PoAManager.go new file mode 100644 index 000000000..c02fbb29e --- /dev/null +++ b/abi-bindings/go/validator-manager/PoAManager/PoAManager.go @@ -0,0 +1,582 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package poamanager + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// PChainOwner is an auto generated low-level Go binding around an user-defined struct. +type PChainOwner struct { + Threshold uint32 + Addresses []common.Address +} + +// PoAManagerMetaData contains all meta data concerning the PoAManager contract. +var PoAManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"contractIValidatorManagerExternalOwnable\",\"name\":\"validatorManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRemoval\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorWeightUpdate\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"initiateValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"initiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"newWeight\",\"type\":\"uint64\"}],\"name\":\"initiateValidatorWeightUpdate\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferValidatorManagerOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561000f575f80fd5b50604051610c49380380610c4983398101604081905261002e916100de565b816001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61006581610078565b506001600160a01b031660805250610116565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146100db575f80fd5b50565b5f80604083850312156100ef575f80fd5b82516100fa816100c7565b602084015190925061010b816100c7565b809150509250929050565b608051610af16101585f395f81816101dc015281816102920152818161030a015281816103a3015281816104470152818161049c01526104fd0152610af15ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c80639cb7624e116100635780639cb7624e1461012f578063a3a65e4814610142578063b6e6a2ca14610155578063ce161f1414610168578063f2fde38b14610199575f80fd5b8063661096691461009f578063715018a6146100d757806389f9f85b146100e15780638da5cb5b146100f45780639681d9401461010e575b5f80fd5b6100b26100ad36600461063e565b6101ac565b6040805167ffffffffffffffff90931683526020830191909152015b60405180910390f35b6100df610258565b005b6100df6100ef366004610687565b61026b565b5f546040516001600160a01b0390911681526020016100ce565b61012161011c3660046106ba565b6102ed565b6040519081526020016100ce565b61012161013d366004610872565b610383565b6101216101503660046106ba565b61042a565b6100df61016336600461092c565b61047e565b61017b6101763660046106ba565b6104d6565b6040805192835267ffffffffffffffff9091166020830152016100ce565b6100df6101a7366004610687565b61056f565b5f806101b66105ae565b604051636610966960e01b81526004810185905267ffffffffffffffff841660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063661096699060440160408051808303815f875af1158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d9190610943565b915091509250929050565b6102606105ae565b6102695f6105da565b565b6102736105ae565b60405163f2fde38b60e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063f2fde38b906024015b5f604051808303815f87803b1580156102d4575f80fd5b505af11580156102e6573d5f803e3d5ffd5b5050505050565b60405163025a076560e61b815263ffffffff821660048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639681d940906024015b6020604051808303815f875af1158015610359573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037d919061096f565b92915050565b5f61038c6105ae565b604051634e5bb12760e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639cb7624e906103e09089908990899089908990600401610a2f565b6020604051808303815f875af11580156103fc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610420919061096f565b9695505050505050565b604051631474cbc960e31b815263ffffffff821660048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a3a65e489060240161033d565b6104866105ae565b604051635b73516560e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b6e6a2ca906024016102bd565b50565b60405163338587c560e21b815263ffffffff821660048201525f9081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ce161f149060240160408051808303815f875af1158015610542573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105669190610a98565b91509150915091565b6105776105ae565b6001600160a01b0381166105a557604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6104d3816105da565b5f546001600160a01b031633146102695760405163118cdaa760e01b815233600482015260240161059c565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b67ffffffffffffffff811681146104d3575f80fd5b5f806040838503121561064f575f80fd5b82359150602083013561066181610629565b809150509250929050565b80356001600160a01b0381168114610682575f80fd5b919050565b5f60208284031215610697575f80fd5b6106a08261066c565b9392505050565b803563ffffffff81168114610682575f80fd5b5f602082840312156106ca575f80fd5b6106a0826106a7565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff8111828210171561070a5761070a6106d3565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610739576107396106d3565b604052919050565b5f82601f830112610750575f80fd5b813567ffffffffffffffff81111561076a5761076a6106d3565b61077d601f8201601f1916602001610710565b818152846020838601011115610791575f80fd5b816020850160208301375f918101602001919091529392505050565b5f604082840312156107bd575f80fd5b6107c56106e7565b90506107d0826106a7565b815260208083013567ffffffffffffffff808211156107ed575f80fd5b818501915085601f830112610800575f80fd5b813581811115610812576108126106d3565b8060051b9150610823848301610710565b818152918301840191848101908884111561083c575f80fd5b938501935b83851015610861576108528561066c565b82529385019390850190610841565b808688015250505050505092915050565b5f805f805f60a08688031215610886575f80fd5b853567ffffffffffffffff8082111561089d575f80fd5b6108a989838a01610741565b965060208801359150808211156108be575f80fd5b6108ca89838a01610741565b955060408801359150808211156108df575f80fd5b6108eb89838a016107ad565b94506060880135915080821115610900575f80fd5b5061090d888289016107ad565b925050608086013561091e81610629565b809150509295509295909350565b5f6020828403121561093c575f80fd5b5035919050565b5f8060408385031215610954575f80fd5b825161095f81610629565b6020939093015192949293505050565b5f6020828403121561097f575f80fd5b5051919050565b5f81518084525f5b818110156109aa5760208185018101518683018201520161098e565b505f602082860101526020601f19601f83011685010191505092915050565b5f6040830163ffffffff8351168452602080840151604060208701528281518085526060880191506020830194505f92505b80831015610a245784516001600160a01b031682529383019360019290920191908301906109fb565b509695505050505050565b60a081525f610a4160a0830188610986565b8281036020840152610a538188610986565b90508281036040840152610a6781876109c9565b90508281036060840152610a7b81866109c9565b91505067ffffffffffffffff831660808301529695505050505050565b5f8060408385031215610aa9575f80fd5b8251915060208301516106618161062956fea2646970667358221220725ca54055c2d2ce072cfc01bc3f4104207fccf3f00f6f4ec34485bda571b2de64736f6c63430008190033", +} + +// PoAManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use PoAManagerMetaData.ABI instead. +var PoAManagerABI = PoAManagerMetaData.ABI + +// PoAManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use PoAManagerMetaData.Bin instead. +var PoAManagerBin = PoAManagerMetaData.Bin + +// DeployPoAManager deploys a new Ethereum contract, binding an instance of PoAManager to it. +func DeployPoAManager(auth *bind.TransactOpts, backend bind.ContractBackend, owner common.Address, validatorManager common.Address) (common.Address, *types.Transaction, *PoAManager, error) { + parsed, err := PoAManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PoAManagerBin), backend, owner, validatorManager) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PoAManager{PoAManagerCaller: PoAManagerCaller{contract: contract}, PoAManagerTransactor: PoAManagerTransactor{contract: contract}, PoAManagerFilterer: PoAManagerFilterer{contract: contract}}, nil +} + +// PoAManager is an auto generated Go binding around an Ethereum contract. +type PoAManager struct { + PoAManagerCaller // Read-only binding to the contract + PoAManagerTransactor // Write-only binding to the contract + PoAManagerFilterer // Log filterer for contract events +} + +// PoAManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type PoAManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoAManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PoAManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoAManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PoAManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoAManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PoAManagerSession struct { + Contract *PoAManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PoAManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PoAManagerCallerSession struct { + Contract *PoAManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PoAManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PoAManagerTransactorSession struct { + Contract *PoAManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PoAManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type PoAManagerRaw struct { + Contract *PoAManager // Generic contract binding to access the raw methods on +} + +// PoAManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PoAManagerCallerRaw struct { + Contract *PoAManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// PoAManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PoAManagerTransactorRaw struct { + Contract *PoAManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPoAManager creates a new instance of PoAManager, bound to a specific deployed contract. +func NewPoAManager(address common.Address, backend bind.ContractBackend) (*PoAManager, error) { + contract, err := bindPoAManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PoAManager{PoAManagerCaller: PoAManagerCaller{contract: contract}, PoAManagerTransactor: PoAManagerTransactor{contract: contract}, PoAManagerFilterer: PoAManagerFilterer{contract: contract}}, nil +} + +// NewPoAManagerCaller creates a new read-only instance of PoAManager, bound to a specific deployed contract. +func NewPoAManagerCaller(address common.Address, caller bind.ContractCaller) (*PoAManagerCaller, error) { + contract, err := bindPoAManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PoAManagerCaller{contract: contract}, nil +} + +// NewPoAManagerTransactor creates a new write-only instance of PoAManager, bound to a specific deployed contract. +func NewPoAManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*PoAManagerTransactor, error) { + contract, err := bindPoAManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PoAManagerTransactor{contract: contract}, nil +} + +// NewPoAManagerFilterer creates a new log filterer instance of PoAManager, bound to a specific deployed contract. +func NewPoAManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*PoAManagerFilterer, error) { + contract, err := bindPoAManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PoAManagerFilterer{contract: contract}, nil +} + +// bindPoAManager binds a generic wrapper to an already deployed contract. +func bindPoAManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PoAManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PoAManager *PoAManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PoAManager.Contract.PoAManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PoAManager *PoAManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoAManager.Contract.PoAManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PoAManager *PoAManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PoAManager.Contract.PoAManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PoAManager *PoAManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PoAManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PoAManager *PoAManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoAManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PoAManager *PoAManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PoAManager.Contract.contract.Transact(opts, method, params...) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PoAManager *PoAManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PoAManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PoAManager *PoAManagerSession) Owner() (common.Address, error) { + return _PoAManager.Contract.Owner(&_PoAManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PoAManager *PoAManagerCallerSession) Owner() (common.Address, error) { + return _PoAManager.Contract.Owner(&_PoAManager.CallOpts) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_PoAManager *PoAManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_PoAManager *PoAManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.Contract.CompleteValidatorRegistration(&_PoAManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_PoAManager *PoAManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.Contract.CompleteValidatorRegistration(&_PoAManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_PoAManager *PoAManagerTransactor) CompleteValidatorRemoval(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "completeValidatorRemoval", messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_PoAManager *PoAManagerSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.Contract.CompleteValidatorRemoval(&_PoAManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_PoAManager *PoAManagerTransactorSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.Contract.CompleteValidatorRemoval(&_PoAManager.TransactOpts, messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32, uint64) +func (_PoAManager *PoAManagerTransactor) CompleteValidatorWeightUpdate(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "completeValidatorWeightUpdate", messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32, uint64) +func (_PoAManager *PoAManagerSession) CompleteValidatorWeightUpdate(messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.Contract.CompleteValidatorWeightUpdate(&_PoAManager.TransactOpts, messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32, uint64) +func (_PoAManager *PoAManagerTransactorSession) CompleteValidatorWeightUpdate(messageIndex uint32) (*types.Transaction, error) { + return _PoAManager.Contract.CompleteValidatorWeightUpdate(&_PoAManager.TransactOpts, messageIndex) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x9cb7624e. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint64 weight) returns(bytes32) +func (_PoAManager *PoAManagerTransactor) InitiateValidatorRegistration(opts *bind.TransactOpts, nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, weight uint64) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "initiateValidatorRegistration", nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x9cb7624e. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint64 weight) returns(bytes32) +func (_PoAManager *PoAManagerSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, weight uint64) (*types.Transaction, error) { + return _PoAManager.Contract.InitiateValidatorRegistration(&_PoAManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x9cb7624e. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint64 weight) returns(bytes32) +func (_PoAManager *PoAManagerTransactorSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, weight uint64) (*types.Transaction, error) { + return _PoAManager.Contract.InitiateValidatorRegistration(&_PoAManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb6e6a2ca. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID) returns() +func (_PoAManager *PoAManagerTransactor) InitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "initiateValidatorRemoval", validationID) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb6e6a2ca. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID) returns() +func (_PoAManager *PoAManagerSession) InitiateValidatorRemoval(validationID [32]byte) (*types.Transaction, error) { + return _PoAManager.Contract.InitiateValidatorRemoval(&_PoAManager.TransactOpts, validationID) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb6e6a2ca. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID) returns() +func (_PoAManager *PoAManagerTransactorSession) InitiateValidatorRemoval(validationID [32]byte) (*types.Transaction, error) { + return _PoAManager.Contract.InitiateValidatorRemoval(&_PoAManager.TransactOpts, validationID) +} + +// InitiateValidatorWeightUpdate is a paid mutator transaction binding the contract method 0x66109669. +// +// Solidity: function initiateValidatorWeightUpdate(bytes32 validationID, uint64 newWeight) returns(uint64, bytes32) +func (_PoAManager *PoAManagerTransactor) InitiateValidatorWeightUpdate(opts *bind.TransactOpts, validationID [32]byte, newWeight uint64) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "initiateValidatorWeightUpdate", validationID, newWeight) +} + +// InitiateValidatorWeightUpdate is a paid mutator transaction binding the contract method 0x66109669. +// +// Solidity: function initiateValidatorWeightUpdate(bytes32 validationID, uint64 newWeight) returns(uint64, bytes32) +func (_PoAManager *PoAManagerSession) InitiateValidatorWeightUpdate(validationID [32]byte, newWeight uint64) (*types.Transaction, error) { + return _PoAManager.Contract.InitiateValidatorWeightUpdate(&_PoAManager.TransactOpts, validationID, newWeight) +} + +// InitiateValidatorWeightUpdate is a paid mutator transaction binding the contract method 0x66109669. +// +// Solidity: function initiateValidatorWeightUpdate(bytes32 validationID, uint64 newWeight) returns(uint64, bytes32) +func (_PoAManager *PoAManagerTransactorSession) InitiateValidatorWeightUpdate(validationID [32]byte, newWeight uint64) (*types.Transaction, error) { + return _PoAManager.Contract.InitiateValidatorWeightUpdate(&_PoAManager.TransactOpts, validationID, newWeight) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PoAManager *PoAManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PoAManager *PoAManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _PoAManager.Contract.RenounceOwnership(&_PoAManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PoAManager *PoAManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _PoAManager.Contract.RenounceOwnership(&_PoAManager.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PoAManager *PoAManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PoAManager *PoAManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PoAManager.Contract.TransferOwnership(&_PoAManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PoAManager *PoAManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PoAManager.Contract.TransferOwnership(&_PoAManager.TransactOpts, newOwner) +} + +// TransferValidatorManagerOwnership is a paid mutator transaction binding the contract method 0x89f9f85b. +// +// Solidity: function transferValidatorManagerOwnership(address newOwner) returns() +func (_PoAManager *PoAManagerTransactor) TransferValidatorManagerOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _PoAManager.contract.Transact(opts, "transferValidatorManagerOwnership", newOwner) +} + +// TransferValidatorManagerOwnership is a paid mutator transaction binding the contract method 0x89f9f85b. +// +// Solidity: function transferValidatorManagerOwnership(address newOwner) returns() +func (_PoAManager *PoAManagerSession) TransferValidatorManagerOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PoAManager.Contract.TransferValidatorManagerOwnership(&_PoAManager.TransactOpts, newOwner) +} + +// TransferValidatorManagerOwnership is a paid mutator transaction binding the contract method 0x89f9f85b. +// +// Solidity: function transferValidatorManagerOwnership(address newOwner) returns() +func (_PoAManager *PoAManagerTransactorSession) TransferValidatorManagerOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PoAManager.Contract.TransferValidatorManagerOwnership(&_PoAManager.TransactOpts, newOwner) +} + +// PoAManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the PoAManager contract. +type PoAManagerOwnershipTransferredIterator struct { + Event *PoAManagerOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAManagerOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAManagerOwnershipTransferred represents a OwnershipTransferred event raised by the PoAManager contract. +type PoAManagerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PoAManager *PoAManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*PoAManagerOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _PoAManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &PoAManagerOwnershipTransferredIterator{contract: _PoAManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PoAManager *PoAManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PoAManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _PoAManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAManagerOwnershipTransferred) + if err := _PoAManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PoAManager *PoAManagerFilterer) ParseOwnershipTransferred(log types.Log) (*PoAManagerOwnershipTransferred, error) { + event := new(PoAManagerOwnershipTransferred) + if err := _PoAManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/validator-manager/ValidatorManager/ValidatorManager.go b/abi-bindings/go/validator-manager/ValidatorManager/ValidatorManager.go new file mode 100644 index 000000000..b21007591 --- /dev/null +++ b/abi-bindings/go/validator-manager/ValidatorManager/ValidatorManager.go @@ -0,0 +1,2891 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package validatormanager + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ConversionData is an auto generated low-level Go binding around an user-defined struct. +type ConversionData struct { + SubnetID [32]byte + ValidatorManagerBlockchainID [32]byte + ValidatorManagerAddress common.Address + InitialValidators []InitialValidator +} + +// InitialValidator is an auto generated low-level Go binding around an user-defined struct. +type InitialValidator struct { + NodeID []byte + BlsPublicKey []byte + Weight uint64 +} + +// PChainOwner is an auto generated low-level Go binding around an user-defined struct. +type PChainOwner struct { + Threshold uint32 + Addresses []common.Address +} + +// Validator is an auto generated low-level Go binding around an user-defined struct. +type Validator struct { + Status uint8 + NodeID []byte + StartingWeight uint64 + SentNonce uint64 + ReceivedNonce uint64 + Weight uint64 + StartTime uint64 + EndTime uint64 +} + +// ValidatorChurnPeriod is an auto generated low-level Go binding around an user-defined struct. +type ValidatorChurnPeriod struct { + StartTime *big.Int + InitialWeight uint64 + TotalWeight uint64 + ChurnAmount uint64 +} + +// ValidatorManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type ValidatorManagerSettings struct { + Admin common.Address + SubnetID [32]byte + ChurnPeriodSeconds uint64 + MaximumChurnPercentage uint8 +} + +// ValidatorMessagesValidationPeriod is an auto generated low-level Go binding around an user-defined struct. +type ValidatorMessagesValidationPeriod struct { + SubnetID [32]byte + NodeID []byte + BlsPublicKey []byte + RegistrationExpiry uint64 + RemainingBalanceOwner PChainOwner + DisableOwner PChainOwner + Weight uint64 +} + +// ValidatorManagerMetaData contains all meta data concerning the ValidatorManager contract. +var ValidatorManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"enumICMInitializable\",\"name\":\"init\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"InvalidBLSKeyLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"churnPeriodLength\",\"type\":\"uint64\"}],\"name\":\"InvalidChurnPeriodLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"encodedConversionID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"expectedConversionID\",\"type\":\"bytes32\"}],\"name\":\"InvalidConversionID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialization\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitializationStatus\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"maximumChurnPercentage\",\"type\":\"uint8\"}],\"name\":\"InvalidMaximumChurnPercentage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"}],\"name\":\"InvalidNodeID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPChainOwnerAddresses\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"addressesLength\",\"type\":\"uint256\"}],\"name\":\"InvalidPChainOwnerThreshold\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"InvalidTotalWeight\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"InvalidValidationID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"validatorManagerAddress\",\"type\":\"address\"}],\"name\":\"InvalidValidatorManagerAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"}],\"name\":\"InvalidValidatorManagerBlockchainID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"enumValidatorStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"InvalidValidatorStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWarpMessage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"}],\"name\":\"InvalidWarpOriginSenderAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceChainID\",\"type\":\"bytes32\"}],\"name\":\"InvalidWarpSourceChainID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"churnAmount\",\"type\":\"uint64\"}],\"name\":\"MaxChurnRateExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"}],\"name\":\"NodeAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"validRegistration\",\"type\":\"bool\"}],\"name\":\"UnexpectedRegistrationStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"CompletedValidatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"CompletedValidatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"CompletedValidatorWeightUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"nodeID\",\"type\":\"bytes20\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"registrationMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"InitiatedValidatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"validatorWeightMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"endTime\",\"type\":\"uint64\"}],\"name\":\"InitiatedValidatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"weightUpdateMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"InitiatedValidatorWeightUpdate\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes20\",\"name\":\"nodeID\",\"type\":\"bytes20\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"RegisteredInitialValidator\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLS_PUBLIC_KEY_LENGTH\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_CHURN_PERCENTAGE_LIMIT\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_CHURN_PERIOD_LENGTH\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"NODE_ID_LENGTH\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"P_CHAIN_BLOCKCHAIN_ID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTRATION_EXPIRY_LENGTH\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VALIDATOR_MANAGER_STORAGE_LOCATION\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WARP_MESSENGER\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRemoval\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorWeightUpdate\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChurnPeriodSeconds\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChurnTracker\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"startTime\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"initialWeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"totalWeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"churnAmount\",\"type\":\"uint64\"}],\"internalType\":\"structValidatorChurnPeriod\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"}],\"name\":\"getNodeValidationID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"getValidator\",\"outputs\":[{\"components\":[{\"internalType\":\"enumValidatorStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"startingWeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sentNonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"receivedNonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"startTime\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"endTime\",\"type\":\"uint64\"}],\"internalType\":\"structValidator\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"churnPeriodSeconds\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"maximumChurnPercentage\",\"type\":\"uint8\"}],\"internalType\":\"structValidatorManagerSettings\",\"name\":\"settings\",\"type\":\"tuple\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"validatorManagerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structInitialValidator[]\",\"name\":\"initialValidators\",\"type\":\"tuple[]\"}],\"internalType\":\"structConversionData\",\"name\":\"conversionData\",\"type\":\"tuple\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initializeValidatorSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"initiateValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"initiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"newWeight\",\"type\":\"uint64\"}],\"name\":\"initiateValidatorWeightUpdate\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isValidatorSetInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1TotalWeight\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"receivedNonce\",\"type\":\"uint32\"}],\"name\":\"migrateFromV1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"resendRegisterValidatorMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"resendValidatorRemovalMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"subnetID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561000f575f80fd5b50604051613dd1380380613dd183398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b613c848061014d5f395ff3fe608060405234801561000f575f80fd5b50600436106101c6575f3560e01c80639681d940116100fe578063bc5fbfec1161009e578063d47a948b1161006e578063d47a948b1461045d578063d5f20ff614610470578063efc008fb146103b8578063f2fde38b14610490575f80fd5b8063bc5fbfec146103eb578063bee0a03f14610412578063c974d1b614610425578063ce161f141461042d575f80fd5b8063b6c2fd41116100d9578063b6c2fd41146103b8578063b6e6a2ca146103c2578063b771b3bc146103d5578063bb0b1938146103e3575f80fd5b80639681d9401461037f5780639cb7624e14610392578063a3a65e48146103a5575f80fd5b80636610966911610169578063732214f811610144578063732214f814610307578063736c87be1461030e5780638280a25a146103215780638da5cb5b1461033b575f80fd5b806366109669146102ba57806366edba73146102ec578063715018a6146102ff575f80fd5b80634d693536116101a45780634d693536146102175780635bd93e881461026f5780635dc1f5351461028757806363e2ca971461029d575f80fd5b806309c1df66146101ca57806320d91b7a146101ef57806330ffe4d714610204575b5f80fd5b6101d26104a3565b6040516001600160401b0390911681526020015b60405180910390f35b6102026101fd366004612e38565b6104be565b005b610202610212366004612e82565b610a7f565b61021f610d2a565b604080516001600160401b03948516815260ff90931660208085019190915282518483015282015184166060808501919091529082015184166080840152015190911660a082015260c0016101e6565b610277610db5565b60405190151581526020016101e6565b61028f610dcc565b6040519081526020016101e6565b6102a5601481565b60405163ffffffff90911681526020016101e6565b6102cd6102c8366004612eb7565b610ddb565b604080516001600160401b0390931683526020830191909152016101e6565b6102026102fa366004612ee5565b610e60565b6102026110ea565b61028f5f81565b61020261031c366004612efc565b6110fd565b610329603081565b60405160ff90911681526020016101e6565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b0390911681526020016101e6565b61028f61038d366004612f1d565b611209565b61028f6103a0366004613119565b611604565b61028f6103b3366004612f1d565b611624565b6101d26201518081565b6102026103d0366004612ee5565b61181a565b6103676005600160991b0181565b6101d261182e565b61028f7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb0081565b610202610420366004612ee5565b611850565b610329601481565b61044061043b366004612f1d565b611970565b604080519283526001600160401b039091166020830152016101e6565b61028f61046b3660046131d2565b611afb565b61048361047e366004612ee5565b611b34565b6040516101e691906132be565b61020261049e366004613374565b611cb9565b5f6104ac611cf3565b600101546001600160401b0316919050565b5f6104c7611cf3565b600781015490915060ff16156104f057604051637fab81e560e01b815260040160405180910390fd5b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610533573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610557919061338f565b836020013514610585576040516372b0a7e760e11b8152602084013560048201526024015b60405180910390fd5b306105966060850160408601613374565b6001600160a01b0316146105d9576105b46060840160408501613374565b604051632f88120d60e21b81526001600160a01b03909116600482015260240161057c565b5f73__$16907f4f2c19a387278bf4c8803bf9f1c2$__634d8478846105fd85611d17565b604001516040518263ffffffff1660e01b815260040161061d91906133a6565b602060405180830381865af4158015610638573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061065c919061338f565b90505f73__$16907f4f2c19a387278bf4c8803bf9f1c2$__6387418b8e866040518263ffffffff1660e01b815260040161069691906134e3565b5f60405180830381865af41580156106b0573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106d791908101906135c1565b90505f6002826040516106ea91906135f2565b602060405180830381855afa158015610705573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190610728919061338f565b90508281146107545760405163baaea89d60e01b8152600481018290526024810184905260440161057c565b5f610762606088018861360d565b905090505f805b828163ffffffff1610156109eb575f61078560608b018b61360d565b8363ffffffff1681811061079b5761079b613652565b90506020028101906107ad9190613666565b6107b69061367a565b80516040519192505f9160068b01916107ce916135f2565b908152602001604051809103902054146107fe57805160405163a41f772f60e01b815261057c91906004016133a6565b805151601414610824578051604051633e08a12560e11b815261057c91906004016133a6565b5f60028b5f01358460405160200161085392919091825260e01b6001600160e01b031916602082015260240190565b60408051601f198184030181529082905261086d916135f2565b602060405180830381855afa158015610888573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906108ab919061338f565b90508089600601835f01516040516108c391906135f2565b90815260408051918290036020908101909220929092555f83815260088c0190915220805460ff1916600217815582516001909101906109039082613772565b50604082810180515f84815260088d016020529290922060028101805492516001600160401b0394851667ffffffffffffffff60801b90941693909317600160c01b858516021790556003018054429093166001600160801b0319909316929092179091556109729085613841565b8251602001519094508b35906bffffffffffffffffffffffff1916827f070e0f6540afd612d613b71036a6d45f8c5fa97770a7e2d55663d75474ce0c0d85604001516040516109d091906001600160401b0391909116815260200190565b60405180910390a45050806109e490613861565b9050610769565b506003860180546fffffffffffffffff00000000000000001916600160401b6001600160401b0384168102919091179091556001870154606491610a33910460ff1683613883565b6001600160401b03161015610a6657604051633e1a785160e01b81526001600160401b038216600482015260240161057c565b5050506007909201805460ff1916600117905550505050565b5f610a88611cf3565b5f8481526005820160205260408120919250815460ff166005811115610ab057610ab061323d565b03610ad15760405163089938b360e11b81526004810185905260240161057c565b6002810154600160401b90046001600160401b031663ffffffff84161115610b1457604051632e19bc2d60e11b815263ffffffff8416600482015260240161057c565b6040805161010081019091528154819060ff166005811115610b3857610b3861323d565b8152602001826001018054610b4c906136f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610b78906136f5565b8015610bc35780601f10610b9a57610100808354040283529160200191610bc3565b820191905f5260205f20905b815481529060010190602001808311610ba657829003601f168201915b505050918352505060028301546001600160401b03808216602080850191909152600160401b8304821660408086019190915263ffffffff89166060860152600160801b840483166080860152600160c01b909304821660a0850152600386015490911660c0909301929092525f87815260088601909252902081518154829060ff19166001836005811115610c5b57610c5b61323d565b021790555060208201516001820190610c749082613772565b506040828101516002830180546060860151608087015160a08801516001600160401b039586166001600160801b031994851617600160401b9387168402176001600160801b0316600160801b928716929092026001600160c01b031691909117600160c01b918616919091021790925560c08601516003909501805460e09097015195841696909116959095179390911602919091179091555f94855260059290920160205250909120805460ff1916905550565b604080516080810182525f808252602082018190529181018290526060810182905281905f610d57611cf3565b600181015460408051608081018252600284015481526003909301546001600160401b038082166020860152600160401b808304821693860193909352600160801b90910481166060850152821697910460ff169550909350915050565b5f80610dbf611cf3565b6007015460ff1692915050565b5f610dd5611cf3565b54919050565b5f80610de5611e2d565b5f610dee611cf3565b905060025f86815260088301602052604090205460ff166005811115610e1657610e1661323d565b14610e49575f8581526008820160205260409081902054905163170cc93360e21b815261057c9160ff16906004016138ae565b610e538585611e88565b92509250505b9250929050565b5f610e69611cf3565b5f8381526008820160205260408082208151610100810190925280549394509192909190829060ff166005811115610ea357610ea361323d565b6005811115610eb457610eb461323d565b8152602001600182018054610ec8906136f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610ef4906136f5565b8015610f3f5780601f10610f1657610100808354040283529160200191610f3f565b820191905f5260205f20905b815481529060010190602001808311610f2257829003601f168201915b505050918352505060028201546001600160401b038082166020840152600160401b80830482166040850152600160801b830482166060850152600160c01b9092048116608084015260039384015480821660a0850152919091041660c09091015290915081516005811115610fb757610fb761323d565b14610fea575f8381526008830160205260409081902054905163170cc93360e21b815261057c9160ff16906004016138ae565b606081015160405163854a893f60e01b8152600481018590526001600160401b0390911660248201525f60448201526005600160991b019063ee5b48eb9073__$16907f4f2c19a387278bf4c8803bf9f1c2$__9063854a893f906064015f60405180830381865af4158015611061573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261108891908101906135c1565b6040518263ffffffff1660e01b81526004016110a491906133a6565b6020604051808303815f875af11580156110c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110e4919061338f565b50505050565b6110f2611e2d565b6110fb5f612050565b565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156111415750825b90505f826001600160401b0316600114801561115c5750303b155b90508115801561116a575080155b156111885760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156111b257845460ff60401b1916600160401b1785555b6111bb866120c0565b831561120157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b5f611212611e2d565b5f61121b611cf3565b90505f8073__$16907f4f2c19a387278bf4c8803bf9f1c2$__63021de88f61124287611d17565b604001516040518263ffffffff1660e01b815260040161126291906133a6565b6040805180830381865af415801561127c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112a091906138cb565b9150915080156112c757604051632d07135360e01b8152811515600482015260240161057c565b5f828152600884016020526040808220815161010081019092528054829060ff1660058111156112f9576112f961323d565b600581111561130a5761130a61323d565b815260200160018201805461131e906136f5565b80601f016020809104026020016040519081016040528092919081815260200182805461134a906136f5565b80156113955780601f1061136c57610100808354040283529160200191611395565b820191905f5260205f20905b81548152906001019060200180831161137857829003601f168201915b505050918352505060028201546001600160401b038082166020840152600160401b80830482166040850152600160801b830482166060850152600160c01b9092048116608084015260039384015480821660a0850152919091041660c0909101529091508151600581111561140d5761140d61323d565b1415801561142e575060018151600581111561142b5761142b61323d565b14155b1561144f57805160405163170cc93360e21b815261057c91906004016138ae565b6003815160058111156114645761146461323d565b0361147257600481526114c3565b60a081015160038501805460089061149b908490600160401b90046001600160401b03166138ec565b82546001600160401b039182166101009390930a928302919092021990911617905550600581525b8360060181602001516040516114d991906135f2565b90815260408051602092819003830190205f908190558581526008870190925290208151815483929190829060ff1916600183600581111561151d5761151d61323d565b0217905550602082015160018201906115369082613772565b506040828101516002830180546060860151608087015160a08801516001600160401b039586166001600160801b031994851617600160401b9387168402176001600160801b0316600160801b928716929092026001600160c01b031691909117600160c01b918616919091021790925560c08601516003909501805460e09097015195841696909116959095179390911602919091179091555183907fafaccef7080649a725bc30a35359a257a4a27225be352875c80bdf6b5f04080c905f90a25090925050505b919050565b5f61160d611e2d565b61161a86868686866120e6565b9695505050505050565b5f61162d611e2d565b5f611636611cf3565b90505f8073__$16907f4f2c19a387278bf4c8803bf9f1c2$__63021de88f61165d87611d17565b604001516040518263ffffffff1660e01b815260040161167d91906133a6565b6040805180830381865af4158015611697573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116bb91906138cb565b91509150806116e157604051632d07135360e01b8152811515600482015260240161057c565b5f828152600484016020526040902080546116fb906136f5565b90505f0361171f5760405163089938b360e11b81526004810183905260240161057c565b60015f83815260088501602052604090205460ff1660058111156117455761174561323d565b14611778575f8281526008840160205260409081902054905163170cc93360e21b815261057c9160ff16906004016138ae565b5f828152600484016020526040812061179091612dc5565b5f828152600884016020908152604091829020805460ff1916600290811782556003820180546001600160401b0342811667ffffffffffffffff19909216919091179091559101549251600160c01b90930416825283917f967ae87813a3b5f201dd9bcba778d457176eafe6f41facee1c718091d3952d06910160405180910390a2509392505050565b611822611e2d565b61182b816124e3565b50565b5f611837611cf3565b60030154600160401b90046001600160401b0316919050565b5f611859611cf3565b5f8381526004820160205260409020805491925090611877906136f5565b90505f0361189b5760405163089938b360e11b81526004810183905260240161057c565b60015f83815260088301602052604090205460ff1660058111156118c1576118c161323d565b146118f4575f8281526008820160205260409081902054905163170cc93360e21b815261057c9160ff16906004016138ae565b5f8281526004808301602052604091829020915163ee5b48eb60e01b81526005600160991b019263ee5b48eb9261192b920161390c565b6020604051808303815f875af1158015611947573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061196b919061338f565b505050565b5f8061197a611e2d565b5f61198484611d17565b90505f805f73__$16907f4f2c19a387278bf4c8803bf9f1c2$__6350782b0f85604001516040518263ffffffff1660e01b81526004016119c491906133a6565b606060405180830381865af41580156119df573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a039190613996565b9250925092505f611a12611cf3565b5f8581526008820160205260409020600201549091506001600160401b03808516600160401b909204161015611a6657604051632e19bc2d60e11b81526001600160401b038416600482015260240161057c565b5f8481526008820160205260409081902060020180546001600160401b038616600160801b0267ffffffffffffffff60801b199091161790555184907fc917996591802ecedcfced71321d4bb5320f7dfbacf5477dffe1dbf8b8839ff990611ae690869086906001600160401b0392831681529116602082015260400190565b60405180910390a25091945092505050915091565b5f80611b05611cf3565b9050806006018484604051611b1b9291906139d6565b9081526020016040518091039020549150505b92915050565b60408051610100810182525f8082526060602083018190529282018190529181018290526080810182905260a0810182905260c0810182905260e0810182905290611b7d611cf3565b5f848152600882016020526040908190208151610100810190925280549293509091829060ff166005811115611bb557611bb561323d565b6005811115611bc657611bc661323d565b8152602001600182018054611bda906136f5565b80601f0160208091040260200160405190810160405280929190818152602001828054611c06906136f5565b8015611c515780601f10611c2857610100808354040283529160200191611c51565b820191905f5260205f20905b815481529060010190602001808311611c3457829003601f168201915b505050918352505060028201546001600160401b038082166020840152600160401b80830482166040850152600160801b830482166060850152600160c01b9092048116608084015260039093015480841660a08401520490911660c0909101529392505050565b611cc1611e2d565b6001600160a01b038116611cea57604051631e4fbdf760e01b81525f600482015260240161057c565b61182b81612050565b7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb0090565b60408051606080820183525f8083526020830152918101919091526040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa158015611d7b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611da291908101906139e5565b9150915080611dc457604051636b2f19e960e01b815260040160405180910390fd5b815115611dea578151604051636ba589a560e01b8152600481019190915260240161057c565b60208201516001600160a01b031615611e26576020820151604051624de75d60e31b81526001600160a01b03909116600482015260240161057c565b5092915050565b33611e5f7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146110fb5760405163118cdaa760e01b815233600482015260240161057c565b5f805f611e93611cf3565b5f868152600882016020526040902060020154909150600160c01b90046001600160401b0316611ec385826127cd565b5f611ecd87612a3a565b5f88815260088501602052604080822060020180546001600160c01b0316600160c01b6001600160401b038c811691820292909217909255915163854a893f60e01b8152600481018c905291841660248301526044820152919250906005600160991b019063ee5b48eb9073__$16907f4f2c19a387278bf4c8803bf9f1c2$__9063854a893f906064015f60405180830381865af4158015611f71573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f9891908101906135c1565b6040518263ffffffff1660e01b8152600401611fb491906133a6565b6020604051808303815f875af1158015611fd0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ff4919061338f565b604080516001600160401b038581168252602082018490528a1681830152905191925089917f6e350dd49b060d87f297206fd309234ed43156d890ced0f139ecf704310481d39181900360600190a29097909650945050505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b6120c8612aa2565b6120dd6120d86020830183613374565b612aeb565b61182b81612afc565b5f6120ef611cf3565b6007015460ff1661211357604051637fab81e560e01b815260040160405180910390fd5b5f61211c611cf3565b60038101549091506001600160401b039061214290600160401b90048216858316613a72565b111561216c57604051633e1a785160e01b81526001600160401b038416600482015260240161057c565b61217585612c3b565b61217e84612c3b565b85516030146121a55785516040516326475b2f60e11b815260040161057c91815260200190565b86516014146121c95786604051633e08a12560e11b815260040161057c91906133a6565b5f801b81600601886040516121de91906135f2565b9081526020016040518091039020541461220d578660405163a41f772f60e01b815260040161057c91906133a6565b612217835f6127cd565b5f6122256201518042613841565b90505f8073__$16907f4f2c19a387278bf4c8803bf9f1c2$__63eb97ce516040518060e00160405280875f015481526020018d81526020018c8152602001866001600160401b031681526020018b81526020018a8152602001896001600160401b03168152506040518263ffffffff1660e01b81526004016122a79190613aeb565b5f60405180830381865af41580156122c1573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526122e89190810190613ba2565b90925090505f8083815260088601602052604090205460ff1660058111156123125761231261323d565b14612345575f8281526008850160205260409081902054905163170cc93360e21b815261057c9160ff16906004016138ae565b5f828152600485016020526040902061235e8282613772565b5081846006018b60405161237291906135f2565b9081526040519081900360200181209190915563ee5b48eb60e01b81525f906005600160991b019063ee5b48eb906123ae9085906004016133a6565b6020604051808303815f875af11580156123ca573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123ee919061338f565b5f8481526008870160205260409020805460ff191660019081178255919250016124188c82613772565b505f8381526008860160205260409020600281018054600160c01b6001600160401b038b1690810267ffffffffffffffff60801b9092161717905560030180546001600160801b031916905561246f8b6020015190565b6bffffffffffffffffffffffff1916837f5881be437bdcb008bfa5f20e32d3e335ccf8ab90ef2818852a251625260af35d83878b6040516124cc939291909283526001600160401b03918216602084015216604082015260600190565b60405180910390a350909998505050505050505050565b5f6124ec611cf3565b5f8381526008820160205260408082208151610100810190925280549394509192909190829060ff1660058111156125265761252661323d565b60058111156125375761253761323d565b815260200160018201805461254b906136f5565b80601f0160208091040260200160405190810160405280929190818152602001828054612577906136f5565b80156125c25780601f10612599576101008083540402835291602001916125c2565b820191905f5260205f20905b8154815290600101906020018083116125a557829003601f168201915b50505091835250506002828101546001600160401b038082166020850152600160401b80830482166040860152600160801b830482166060860152600160c01b9092048116608085015260039094015480851660a08501520490921660c0909101529091508151600581111561263a5761263a61323d565b1461266d575f8381526008830160205260409081902054905163170cc93360e21b815261057c9160ff16906004016138ae565b60038152426001600160401b031660e08201525f83815260088301602052604090208151815483929190829060ff191660018360058111156126b1576126b161323d565b0217905550602082015160018201906126ca9082613772565b5060408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031994851617600160401b9387168402176001600160801b0316600160801b928716929092026001600160c01b031691909117600160c01b918616919091021790925560c08501516003909401805460e090960151948416959091169490941792909116021790555f61276a8482611e88565b915050837fbae388a94e7f18411fe57098f12f418b8e1a8273e0532a90188a3a059b897273828460a00151426040516127bf939291909283526001600160401b03918216602084015216604082015260600190565b60405180910390a250505050565b5f6127d6611cf3565b90505f826001600160401b0316846001600160401b03161115612804576127fd83856138ec565b9050612811565b61280e84846138ec565b90505b60408051608081018252600284015480825260038501546001600160401b038082166020850152600160401b8204811694840194909452600160801b900490921660608201524291158061287e57506001840154815161287a916001600160401b031690613a72565b8210155b156128a6576001600160401b03808416606083015282825260408201511660208201526128c5565b82816060018181516128b89190613841565b6001600160401b03169052505b60608101516128d5906064613883565b602082015160018601546001600160401b0392909216916129009190600160401b900460ff16613883565b6001600160401b0316101561293957606081015160405163dfae880160e01b81526001600160401b03909116600482015260240161057c565b858160400181815161294b9190613841565b6001600160401b031690525060408101805186919061296b9083906138ec565b6001600160401b03169052506001840154604082015160649161299991600160401b90910460ff1690613883565b6001600160401b031610156129d2576040808201519051633e1a785160e01b81526001600160401b03909116600482015260240161057c565b8051600285015560208101516003909401805460408301516060909301516001600160401b03908116600160801b0267ffffffffffffffff60801b19948216600160401b026001600160801b0319909316919097161717919091169390931790925550505050565b5f80612a44611cf3565b5f84815260088281016020526040909120600201805492935091612a7790600160401b90046001600160401b0316613be5565b91906101000a8154816001600160401b0302191690836001600160401b031602179055915050919050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166110fb57604051631afcd79f60e31b815260040160405180910390fd5b612af3612aa2565b61182b81612dbd565b612b04612aa2565b5f612b0d611cf3565b6020830135815590506014612b286080840160608501613c00565b60ff161180612b475750612b426080830160608401613c00565b60ff16155b15612b7b57612b5c6080830160608401613c00565b604051634a59bbff60e11b815260ff909116600482015260240161057c565b62015180612b8f6060840160408501613c20565b6001600160401b03161115612bd357612bae6060830160408401613c20565b6040516301f2f3ff60e51b81526001600160401b03909116600482015260240161057c565b612be36080830160608401613c00565b60018201805460ff92909216600160401b0260ff60401b19909216919091179055612c146060830160408401613c20565b600191909101805467ffffffffffffffff19166001600160401b0390921691909117905550565b805163ffffffff16158015612c54575060208101515115155b15612c8857805160208201515160405163c08a0f1d60e01b815263ffffffff9092166004830152602482015260440161057c565b602081015151815163ffffffff161115612ccb57805160208201515160405163c08a0f1d60e01b815263ffffffff9092166004830152602482015260440161057c565b5f816020015151118015612d0d57505f6001600160a01b031681602001515f81518110612cfa57612cfa613652565b60200260200101516001600160a01b0316145b15612d2b5760405163d92e233d60e01b815260040160405180910390fd5b60015b816020015151811015612db9576020820151612d4b600183613c3b565b81518110612d5b57612d5b613652565b60200260200101516001600160a01b031682602001518281518110612d8257612d82613652565b60200260200101516001600160a01b031611612db157604051637882c48760e01b815260040160405180910390fd5b600101612d2e565b5050565b611cc1612aa2565b508054612dd1906136f5565b5f825580601f10612de0575050565b601f0160209004905f5260205f209081019061182b91905b80821115612e0b575f8155600101612df8565b5090565b5f60808284031215612e1f575f80fd5b50919050565b803563ffffffff811681146115ff575f80fd5b5f8060408385031215612e49575f80fd5b82356001600160401b03811115612e5e575f80fd5b612e6a85828601612e0f565b925050612e7960208401612e25565b90509250929050565b5f8060408385031215612e93575f80fd5b82359150612e7960208401612e25565b6001600160401b038116811461182b575f80fd5b5f8060408385031215612ec8575f80fd5b823591506020830135612eda81612ea3565b809150509250929050565b5f60208284031215612ef5575f80fd5b5035919050565b5f60808284031215612f0c575f80fd5b612f168383612e0f565b9392505050565b5f60208284031215612f2d575f80fd5b612f1682612e25565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715612f6c57612f6c612f36565b60405290565b604051606081016001600160401b0381118282101715612f6c57612f6c612f36565b604051601f8201601f191681016001600160401b0381118282101715612fbc57612fbc612f36565b604052919050565b5f6001600160401b03821115612fdc57612fdc612f36565b50601f01601f191660200190565b5f82601f830112612ff9575f80fd5b813561300c61300782612fc4565b612f94565b818152846020838601011115613020575f80fd5b816020850160208301375f918101602001919091529392505050565b6001600160a01b038116811461182b575f80fd5b5f60408284031215613060575f80fd5b613068612f4a565b905061307382612e25565b81526020808301356001600160401b038082111561308f575f80fd5b818501915085601f8301126130a2575f80fd5b8135818111156130b4576130b4612f36565b8060051b91506130c5848301612f94565b81815291830184019184810190888411156130de575f80fd5b938501935b8385101561310857843592506130f88361303c565b82825293850193908501906130e3565b808688015250505050505092915050565b5f805f805f60a0868803121561312d575f80fd5b85356001600160401b0380821115613143575f80fd5b61314f89838a01612fea565b96506020880135915080821115613164575f80fd5b61317089838a01612fea565b95506040880135915080821115613185575f80fd5b61319189838a01613050565b945060608801359150808211156131a6575f80fd5b506131b388828901613050565b92505060808601356131c481612ea3565b809150509295509295909350565b5f80602083850312156131e3575f80fd5b82356001600160401b03808211156131f9575f80fd5b818501915085601f83011261320c575f80fd5b81358181111561321a575f80fd5b86602082850101111561322b575f80fd5b60209290920196919550909350505050565b634e487b7160e01b5f52602160045260245ffd5b6006811061326d57634e487b7160e01b5f52602160045260245ffd5b9052565b5f5b8381101561328b578181015183820152602001613273565b50505f910152565b5f81518084526132aa816020860160208601613271565b601f01601f19169290920160200192915050565b602081526132d0602082018351613251565b5f60208301516101008060408501526132ed610120850183613293565b915060408501516001600160401b0380821660608701528060608801511660808701525050608085015161332c60a08601826001600160401b03169052565b5060a08501516001600160401b03811660c08601525060c08501516001600160401b03811660e08601525060e08501516001600160401b038116858301525090949350505050565b5f60208284031215613384575f80fd5b8135612f168161303c565b5f6020828403121561339f575f80fd5b5051919050565b602081525f612f166020830184613293565b5f808335601e198436030181126133cd575f80fd5b83016020810192503590506001600160401b038111156133eb575f80fd5b803603821315610e59575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f8383855260208086019550808560051b830101845f5b878110156134d657848303601f19018952813536889003605e1901811261345d575f80fd5b8701606061346b82806133b8565b82875261347b83880182846133f9565b9250505061348b868301836133b8565b8683038888015261349d8382846133f9565b9250505060408083013592506134b283612ea3565b6001600160401b039290921694909101939093529783019790830190600101613438565b5090979650505050505050565b6020815281356020820152602082013560408201525f60408301356135078161303c565b6001600160a01b031660608381019190915283013536849003601e1901811261352e575f80fd5b83016020810190356001600160401b03811115613549575f80fd5b8060051b360382131561355a575f80fd5b60808085015261356e60a085018284613421565b95945050505050565b5f82601f830112613586575f80fd5b815161359461300782612fc4565b8181528460208386010111156135a8575f80fd5b6135b9826020830160208701613271565b949350505050565b5f602082840312156135d1575f80fd5b81516001600160401b038111156135e6575f80fd5b6135b984828501613577565b5f8251613603818460208701613271565b9190910192915050565b5f808335601e19843603018112613622575f80fd5b8301803591506001600160401b0382111561363b575f80fd5b6020019150600581901b3603821315610e59575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112613603575f80fd5b5f6060823603121561368a575f80fd5b613692612f72565b82356001600160401b03808211156136a8575f80fd5b6136b436838701612fea565b835260208501359150808211156136c9575f80fd5b506136d636828601612fea565b60208301525060408301356136ea81612ea3565b604082015292915050565b600181811c9082168061370957607f821691505b602082108103612e1f57634e487b7160e01b5f52602260045260245ffd5b601f82111561196b57805f5260205f20601f840160051c8101602085101561374c5750805b601f840160051c820191505b8181101561376b575f8155600101613758565b5050505050565b81516001600160401b0381111561378b5761378b612f36565b61379f8161379984546136f5565b84613727565b602080601f8311600181146137d2575f84156137bb5750858301515b5f19600386901b1c1916600185901b178555611201565b5f85815260208120601f198616915b82811015613800578886015182559484019460019091019084016137e1565b508582101561381d57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b03818116838216019080821115611e2657611e2661382d565b5f63ffffffff8083168181036138795761387961382d565b6001019392505050565b6001600160401b038181168382160280821691908281146138a6576138a661382d565b505092915050565b60208101611b2e8284613251565b805180151581146115ff575f80fd5b5f80604083850312156138dc575f80fd5b82519150612e79602084016138bc565b6001600160401b03828116828216039080821115611e2657611e2661382d565b5f60208083525f845461391e816136f5565b806020870152604060018084165f811461393f576001811461395b57613988565b60ff19851660408a0152604084151560051b8a01019550613988565b895f5260205f205f5b8581101561397f5781548b8201860152908301908801613964565b8a016040019650505b509398975050505050505050565b5f805f606084860312156139a8575f80fd5b8351925060208401516139ba81612ea3565b60408501519092506139cb81612ea3565b809150509250925092565b818382375f9101908152919050565b5f80604083850312156139f6575f80fd5b82516001600160401b0380821115613a0c575f80fd5b9084019060608287031215613a1f575f80fd5b613a27612f72565b825181526020830151613a398161303c565b6020820152604083015182811115613a4f575f80fd5b613a5b88828601613577565b6040830152509350612e79915050602084016138bc565b80820180821115611b2e57611b2e61382d565b5f6040830163ffffffff8351168452602080840151604060208701528281518085526060880191506020830194505f92505b80831015613ae05784516001600160a01b03168252938301936001929092019190830190613ab7565b509695505050505050565b60208152815160208201525f602083015160e06040840152613b11610100840182613293565b90506040840151601f1980858403016060860152613b2f8383613293565b92506001600160401b03606087015116608086015260808601519150808584030160a0860152613b5f8383613a85565b925060a08601519150808584030160c086015250613b7d8282613a85565b91505060c0840151613b9a60e08501826001600160401b03169052565b509392505050565b5f8060408385031215613bb3575f80fd5b8251915060208301516001600160401b03811115613bcf575f80fd5b613bdb85828601613577565b9150509250929050565b5f6001600160401b038083168181036138795761387961382d565b5f60208284031215613c10575f80fd5b813560ff81168114612f16575f80fd5b5f60208284031215613c30575f80fd5b8135612f1681612ea3565b81810381811115611b2e57611b2e61382d56fea2646970667358221220ec3003d4ef6c59f74d31d7594d6fa6879689fce42d3b7e246c06925d1f1119fb64736f6c63430008190033", +} + +// ValidatorManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ValidatorManagerMetaData.ABI instead. +var ValidatorManagerABI = ValidatorManagerMetaData.ABI + +// ValidatorManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ValidatorManagerMetaData.Bin instead. +var ValidatorManagerBin = ValidatorManagerMetaData.Bin + +// DeployValidatorManager deploys a new Ethereum contract, binding an instance of ValidatorManager to it. +func DeployValidatorManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *ValidatorManager, error) { + parsed, err := ValidatorManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + validatorMessagesAddr, _, _, _ := DeployValidatorMessages(auth, backend) + ValidatorManagerBin = strings.ReplaceAll(ValidatorManagerBin, "__$16907f4f2c19a387278bf4c8803bf9f1c2$__", validatorMessagesAddr.String()[2:]) + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ValidatorManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ValidatorManager{ValidatorManagerCaller: ValidatorManagerCaller{contract: contract}, ValidatorManagerTransactor: ValidatorManagerTransactor{contract: contract}, ValidatorManagerFilterer: ValidatorManagerFilterer{contract: contract}}, nil +} + +// ValidatorManager is an auto generated Go binding around an Ethereum contract. +type ValidatorManager struct { + ValidatorManagerCaller // Read-only binding to the contract + ValidatorManagerTransactor // Write-only binding to the contract + ValidatorManagerFilterer // Log filterer for contract events +} + +// ValidatorManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ValidatorManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ValidatorManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ValidatorManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ValidatorManagerSession struct { + Contract *ValidatorManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ValidatorManagerCallerSession struct { + Contract *ValidatorManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ValidatorManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ValidatorManagerTransactorSession struct { + Contract *ValidatorManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ValidatorManagerRaw struct { + Contract *ValidatorManager // Generic contract binding to access the raw methods on +} + +// ValidatorManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ValidatorManagerCallerRaw struct { + Contract *ValidatorManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ValidatorManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ValidatorManagerTransactorRaw struct { + Contract *ValidatorManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewValidatorManager creates a new instance of ValidatorManager, bound to a specific deployed contract. +func NewValidatorManager(address common.Address, backend bind.ContractBackend) (*ValidatorManager, error) { + contract, err := bindValidatorManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ValidatorManager{ValidatorManagerCaller: ValidatorManagerCaller{contract: contract}, ValidatorManagerTransactor: ValidatorManagerTransactor{contract: contract}, ValidatorManagerFilterer: ValidatorManagerFilterer{contract: contract}}, nil +} + +// NewValidatorManagerCaller creates a new read-only instance of ValidatorManager, bound to a specific deployed contract. +func NewValidatorManagerCaller(address common.Address, caller bind.ContractCaller) (*ValidatorManagerCaller, error) { + contract, err := bindValidatorManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ValidatorManagerCaller{contract: contract}, nil +} + +// NewValidatorManagerTransactor creates a new write-only instance of ValidatorManager, bound to a specific deployed contract. +func NewValidatorManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorManagerTransactor, error) { + contract, err := bindValidatorManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ValidatorManagerTransactor{contract: contract}, nil +} + +// NewValidatorManagerFilterer creates a new log filterer instance of ValidatorManager, bound to a specific deployed contract. +func NewValidatorManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorManagerFilterer, error) { + contract, err := bindValidatorManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ValidatorManagerFilterer{contract: contract}, nil +} + +// bindValidatorManager binds a generic wrapper to an already deployed contract. +func bindValidatorManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ValidatorManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorManager *ValidatorManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorManager.Contract.ValidatorManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorManager *ValidatorManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorManager.Contract.ValidatorManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorManager *ValidatorManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorManager.Contract.ValidatorManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorManager *ValidatorManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorManager *ValidatorManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorManager *ValidatorManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorManager.Contract.contract.Transact(opts, method, params...) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_ValidatorManager *ValidatorManagerCaller) BLSPUBLICKEYLENGTH(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "BLS_PUBLIC_KEY_LENGTH") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_ValidatorManager *ValidatorManagerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _ValidatorManager.Contract.BLSPUBLICKEYLENGTH(&_ValidatorManager.CallOpts) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_ValidatorManager *ValidatorManagerCallerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _ValidatorManager.Contract.BLSPUBLICKEYLENGTH(&_ValidatorManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_ValidatorManager *ValidatorManagerCaller) MAXIMUMCHURNPERCENTAGELIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "MAXIMUM_CHURN_PERCENTAGE_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_ValidatorManager *ValidatorManagerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _ValidatorManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_ValidatorManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_ValidatorManager *ValidatorManagerCallerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _ValidatorManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_ValidatorManager.CallOpts) +} + +// MAXIMUMCHURNPERIODLENGTH is a free data retrieval call binding the contract method 0xb6c2fd41. +// +// Solidity: function MAXIMUM_CHURN_PERIOD_LENGTH() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCaller) MAXIMUMCHURNPERIODLENGTH(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "MAXIMUM_CHURN_PERIOD_LENGTH") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// MAXIMUMCHURNPERIODLENGTH is a free data retrieval call binding the contract method 0xb6c2fd41. +// +// Solidity: function MAXIMUM_CHURN_PERIOD_LENGTH() view returns(uint64) +func (_ValidatorManager *ValidatorManagerSession) MAXIMUMCHURNPERIODLENGTH() (uint64, error) { + return _ValidatorManager.Contract.MAXIMUMCHURNPERIODLENGTH(&_ValidatorManager.CallOpts) +} + +// MAXIMUMCHURNPERIODLENGTH is a free data retrieval call binding the contract method 0xb6c2fd41. +// +// Solidity: function MAXIMUM_CHURN_PERIOD_LENGTH() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCallerSession) MAXIMUMCHURNPERIODLENGTH() (uint64, error) { + return _ValidatorManager.Contract.MAXIMUMCHURNPERIODLENGTH(&_ValidatorManager.CallOpts) +} + +// NODEIDLENGTH is a free data retrieval call binding the contract method 0x63e2ca97. +// +// Solidity: function NODE_ID_LENGTH() view returns(uint32) +func (_ValidatorManager *ValidatorManagerCaller) NODEIDLENGTH(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "NODE_ID_LENGTH") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// NODEIDLENGTH is a free data retrieval call binding the contract method 0x63e2ca97. +// +// Solidity: function NODE_ID_LENGTH() view returns(uint32) +func (_ValidatorManager *ValidatorManagerSession) NODEIDLENGTH() (uint32, error) { + return _ValidatorManager.Contract.NODEIDLENGTH(&_ValidatorManager.CallOpts) +} + +// NODEIDLENGTH is a free data retrieval call binding the contract method 0x63e2ca97. +// +// Solidity: function NODE_ID_LENGTH() view returns(uint32) +func (_ValidatorManager *ValidatorManagerCallerSession) NODEIDLENGTH() (uint32, error) { + return _ValidatorManager.Contract.NODEIDLENGTH(&_ValidatorManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCaller) PCHAINBLOCKCHAINID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "P_CHAIN_BLOCKCHAIN_ID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _ValidatorManager.Contract.PCHAINBLOCKCHAINID(&_ValidatorManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCallerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _ValidatorManager.Contract.PCHAINBLOCKCHAINID(&_ValidatorManager.CallOpts) +} + +// REGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xefc008fb. +// +// Solidity: function REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCaller) REGISTRATIONEXPIRYLENGTH(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "REGISTRATION_EXPIRY_LENGTH") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// REGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xefc008fb. +// +// Solidity: function REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_ValidatorManager *ValidatorManagerSession) REGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _ValidatorManager.Contract.REGISTRATIONEXPIRYLENGTH(&_ValidatorManager.CallOpts) +} + +// REGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xefc008fb. +// +// Solidity: function REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCallerSession) REGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _ValidatorManager.Contract.REGISTRATIONEXPIRYLENGTH(&_ValidatorManager.CallOpts) +} + +// VALIDATORMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0xbc5fbfec. +// +// Solidity: function VALIDATOR_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCaller) VALIDATORMANAGERSTORAGELOCATION(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "VALIDATOR_MANAGER_STORAGE_LOCATION") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// VALIDATORMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0xbc5fbfec. +// +// Solidity: function VALIDATOR_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerSession) VALIDATORMANAGERSTORAGELOCATION() ([32]byte, error) { + return _ValidatorManager.Contract.VALIDATORMANAGERSTORAGELOCATION(&_ValidatorManager.CallOpts) +} + +// VALIDATORMANAGERSTORAGELOCATION is a free data retrieval call binding the contract method 0xbc5fbfec. +// +// Solidity: function VALIDATOR_MANAGER_STORAGE_LOCATION() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCallerSession) VALIDATORMANAGERSTORAGELOCATION() ([32]byte, error) { + return _ValidatorManager.Contract.VALIDATORMANAGERSTORAGELOCATION(&_ValidatorManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ValidatorManager *ValidatorManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ValidatorManager *ValidatorManagerSession) WARPMESSENGER() (common.Address, error) { + return _ValidatorManager.Contract.WARPMESSENGER(&_ValidatorManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ValidatorManager *ValidatorManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _ValidatorManager.Contract.WARPMESSENGER(&_ValidatorManager.CallOpts) +} + +// GetChurnPeriodSeconds is a free data retrieval call binding the contract method 0x09c1df66. +// +// Solidity: function getChurnPeriodSeconds() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCaller) GetChurnPeriodSeconds(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "getChurnPeriodSeconds") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// GetChurnPeriodSeconds is a free data retrieval call binding the contract method 0x09c1df66. +// +// Solidity: function getChurnPeriodSeconds() view returns(uint64) +func (_ValidatorManager *ValidatorManagerSession) GetChurnPeriodSeconds() (uint64, error) { + return _ValidatorManager.Contract.GetChurnPeriodSeconds(&_ValidatorManager.CallOpts) +} + +// GetChurnPeriodSeconds is a free data retrieval call binding the contract method 0x09c1df66. +// +// Solidity: function getChurnPeriodSeconds() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCallerSession) GetChurnPeriodSeconds() (uint64, error) { + return _ValidatorManager.Contract.GetChurnPeriodSeconds(&_ValidatorManager.CallOpts) +} + +// GetChurnTracker is a free data retrieval call binding the contract method 0x4d693536. +// +// Solidity: function getChurnTracker() view returns(uint64, uint8, (uint256,uint64,uint64,uint64)) +func (_ValidatorManager *ValidatorManagerCaller) GetChurnTracker(opts *bind.CallOpts) (uint64, uint8, ValidatorChurnPeriod, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "getChurnTracker") + + if err != nil { + return *new(uint64), *new(uint8), *new(ValidatorChurnPeriod), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + out1 := *abi.ConvertType(out[1], new(uint8)).(*uint8) + out2 := *abi.ConvertType(out[2], new(ValidatorChurnPeriod)).(*ValidatorChurnPeriod) + + return out0, out1, out2, err + +} + +// GetChurnTracker is a free data retrieval call binding the contract method 0x4d693536. +// +// Solidity: function getChurnTracker() view returns(uint64, uint8, (uint256,uint64,uint64,uint64)) +func (_ValidatorManager *ValidatorManagerSession) GetChurnTracker() (uint64, uint8, ValidatorChurnPeriod, error) { + return _ValidatorManager.Contract.GetChurnTracker(&_ValidatorManager.CallOpts) +} + +// GetChurnTracker is a free data retrieval call binding the contract method 0x4d693536. +// +// Solidity: function getChurnTracker() view returns(uint64, uint8, (uint256,uint64,uint64,uint64)) +func (_ValidatorManager *ValidatorManagerCallerSession) GetChurnTracker() (uint64, uint8, ValidatorChurnPeriod, error) { + return _ValidatorManager.Contract.GetChurnTracker(&_ValidatorManager.CallOpts) +} + +// GetNodeValidationID is a free data retrieval call binding the contract method 0xd47a948b. +// +// Solidity: function getNodeValidationID(bytes nodeID) view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCaller) GetNodeValidationID(opts *bind.CallOpts, nodeID []byte) ([32]byte, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "getNodeValidationID", nodeID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetNodeValidationID is a free data retrieval call binding the contract method 0xd47a948b. +// +// Solidity: function getNodeValidationID(bytes nodeID) view returns(bytes32) +func (_ValidatorManager *ValidatorManagerSession) GetNodeValidationID(nodeID []byte) ([32]byte, error) { + return _ValidatorManager.Contract.GetNodeValidationID(&_ValidatorManager.CallOpts, nodeID) +} + +// GetNodeValidationID is a free data retrieval call binding the contract method 0xd47a948b. +// +// Solidity: function getNodeValidationID(bytes nodeID) view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCallerSession) GetNodeValidationID(nodeID []byte) ([32]byte, error) { + return _ValidatorManager.Contract.GetNodeValidationID(&_ValidatorManager.CallOpts, nodeID) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes,uint64,uint64,uint64,uint64,uint64,uint64)) +func (_ValidatorManager *ValidatorManagerCaller) GetValidator(opts *bind.CallOpts, validationID [32]byte) (Validator, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "getValidator", validationID) + + if err != nil { + return *new(Validator), err + } + + out0 := *abi.ConvertType(out[0], new(Validator)).(*Validator) + + return out0, err + +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes,uint64,uint64,uint64,uint64,uint64,uint64)) +func (_ValidatorManager *ValidatorManagerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _ValidatorManager.Contract.GetValidator(&_ValidatorManager.CallOpts, validationID) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes,uint64,uint64,uint64,uint64,uint64,uint64)) +func (_ValidatorManager *ValidatorManagerCallerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _ValidatorManager.Contract.GetValidator(&_ValidatorManager.CallOpts, validationID) +} + +// IsValidatorSetInitialized is a free data retrieval call binding the contract method 0x5bd93e88. +// +// Solidity: function isValidatorSetInitialized() view returns(bool) +func (_ValidatorManager *ValidatorManagerCaller) IsValidatorSetInitialized(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "isValidatorSetInitialized") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsValidatorSetInitialized is a free data retrieval call binding the contract method 0x5bd93e88. +// +// Solidity: function isValidatorSetInitialized() view returns(bool) +func (_ValidatorManager *ValidatorManagerSession) IsValidatorSetInitialized() (bool, error) { + return _ValidatorManager.Contract.IsValidatorSetInitialized(&_ValidatorManager.CallOpts) +} + +// IsValidatorSetInitialized is a free data retrieval call binding the contract method 0x5bd93e88. +// +// Solidity: function isValidatorSetInitialized() view returns(bool) +func (_ValidatorManager *ValidatorManagerCallerSession) IsValidatorSetInitialized() (bool, error) { + return _ValidatorManager.Contract.IsValidatorSetInitialized(&_ValidatorManager.CallOpts) +} + +// L1TotalWeight is a free data retrieval call binding the contract method 0xbb0b1938. +// +// Solidity: function l1TotalWeight() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCaller) L1TotalWeight(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "l1TotalWeight") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// L1TotalWeight is a free data retrieval call binding the contract method 0xbb0b1938. +// +// Solidity: function l1TotalWeight() view returns(uint64) +func (_ValidatorManager *ValidatorManagerSession) L1TotalWeight() (uint64, error) { + return _ValidatorManager.Contract.L1TotalWeight(&_ValidatorManager.CallOpts) +} + +// L1TotalWeight is a free data retrieval call binding the contract method 0xbb0b1938. +// +// Solidity: function l1TotalWeight() view returns(uint64) +func (_ValidatorManager *ValidatorManagerCallerSession) L1TotalWeight() (uint64, error) { + return _ValidatorManager.Contract.L1TotalWeight(&_ValidatorManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ValidatorManager *ValidatorManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ValidatorManager *ValidatorManagerSession) Owner() (common.Address, error) { + return _ValidatorManager.Contract.Owner(&_ValidatorManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ValidatorManager *ValidatorManagerCallerSession) Owner() (common.Address, error) { + return _ValidatorManager.Contract.Owner(&_ValidatorManager.CallOpts) +} + +// SubnetID is a free data retrieval call binding the contract method 0x5dc1f535. +// +// Solidity: function subnetID() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCaller) SubnetID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ValidatorManager.contract.Call(opts, &out, "subnetID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// SubnetID is a free data retrieval call binding the contract method 0x5dc1f535. +// +// Solidity: function subnetID() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerSession) SubnetID() ([32]byte, error) { + return _ValidatorManager.Contract.SubnetID(&_ValidatorManager.CallOpts) +} + +// SubnetID is a free data retrieval call binding the contract method 0x5dc1f535. +// +// Solidity: function subnetID() view returns(bytes32) +func (_ValidatorManager *ValidatorManagerCallerSession) SubnetID() ([32]byte, error) { + return _ValidatorManager.Contract.SubnetID(&_ValidatorManager.CallOpts) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_ValidatorManager *ValidatorManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_ValidatorManager *ValidatorManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.CompleteValidatorRegistration(&_ValidatorManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_ValidatorManager *ValidatorManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.CompleteValidatorRegistration(&_ValidatorManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_ValidatorManager *ValidatorManagerTransactor) CompleteValidatorRemoval(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "completeValidatorRemoval", messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_ValidatorManager *ValidatorManagerSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.CompleteValidatorRemoval(&_ValidatorManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_ValidatorManager *ValidatorManagerTransactorSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.CompleteValidatorRemoval(&_ValidatorManager.TransactOpts, messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32, uint64) +func (_ValidatorManager *ValidatorManagerTransactor) CompleteValidatorWeightUpdate(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "completeValidatorWeightUpdate", messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32, uint64) +func (_ValidatorManager *ValidatorManagerSession) CompleteValidatorWeightUpdate(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.CompleteValidatorWeightUpdate(&_ValidatorManager.TransactOpts, messageIndex) +} + +// CompleteValidatorWeightUpdate is a paid mutator transaction binding the contract method 0xce161f14. +// +// Solidity: function completeValidatorWeightUpdate(uint32 messageIndex) returns(bytes32, uint64) +func (_ValidatorManager *ValidatorManagerTransactorSession) CompleteValidatorWeightUpdate(messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.CompleteValidatorWeightUpdate(&_ValidatorManager.TransactOpts, messageIndex) +} + +// Initialize is a paid mutator transaction binding the contract method 0x736c87be. +// +// Solidity: function initialize((address,bytes32,uint64,uint8) settings) returns() +func (_ValidatorManager *ValidatorManagerTransactor) Initialize(opts *bind.TransactOpts, settings ValidatorManagerSettings) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "initialize", settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x736c87be. +// +// Solidity: function initialize((address,bytes32,uint64,uint8) settings) returns() +func (_ValidatorManager *ValidatorManagerSession) Initialize(settings ValidatorManagerSettings) (*types.Transaction, error) { + return _ValidatorManager.Contract.Initialize(&_ValidatorManager.TransactOpts, settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x736c87be. +// +// Solidity: function initialize((address,bytes32,uint64,uint8) settings) returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) Initialize(settings ValidatorManagerSettings) (*types.Transaction, error) { + return _ValidatorManager.Contract.Initialize(&_ValidatorManager.TransactOpts, settings) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x20d91b7a. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData, uint32 messageIndex) returns() +func (_ValidatorManager *ValidatorManagerTransactor) InitializeValidatorSet(opts *bind.TransactOpts, conversionData ConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "initializeValidatorSet", conversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x20d91b7a. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData, uint32 messageIndex) returns() +func (_ValidatorManager *ValidatorManagerSession) InitializeValidatorSet(conversionData ConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitializeValidatorSet(&_ValidatorManager.TransactOpts, conversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x20d91b7a. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData, uint32 messageIndex) returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) InitializeValidatorSet(conversionData ConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitializeValidatorSet(&_ValidatorManager.TransactOpts, conversionData, messageIndex) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x9cb7624e. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint64 weight) returns(bytes32) +func (_ValidatorManager *ValidatorManagerTransactor) InitiateValidatorRegistration(opts *bind.TransactOpts, nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, weight uint64) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "initiateValidatorRegistration", nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x9cb7624e. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint64 weight) returns(bytes32) +func (_ValidatorManager *ValidatorManagerSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, weight uint64) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitiateValidatorRegistration(&_ValidatorManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight) +} + +// InitiateValidatorRegistration is a paid mutator transaction binding the contract method 0x9cb7624e. +// +// Solidity: function initiateValidatorRegistration(bytes nodeID, bytes blsPublicKey, (uint32,address[]) remainingBalanceOwner, (uint32,address[]) disableOwner, uint64 weight) returns(bytes32) +func (_ValidatorManager *ValidatorManagerTransactorSession) InitiateValidatorRegistration(nodeID []byte, blsPublicKey []byte, remainingBalanceOwner PChainOwner, disableOwner PChainOwner, weight uint64) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitiateValidatorRegistration(&_ValidatorManager.TransactOpts, nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb6e6a2ca. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerTransactor) InitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "initiateValidatorRemoval", validationID) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb6e6a2ca. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerSession) InitiateValidatorRemoval(validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitiateValidatorRemoval(&_ValidatorManager.TransactOpts, validationID) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb6e6a2ca. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) InitiateValidatorRemoval(validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitiateValidatorRemoval(&_ValidatorManager.TransactOpts, validationID) +} + +// InitiateValidatorWeightUpdate is a paid mutator transaction binding the contract method 0x66109669. +// +// Solidity: function initiateValidatorWeightUpdate(bytes32 validationID, uint64 newWeight) returns(uint64, bytes32) +func (_ValidatorManager *ValidatorManagerTransactor) InitiateValidatorWeightUpdate(opts *bind.TransactOpts, validationID [32]byte, newWeight uint64) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "initiateValidatorWeightUpdate", validationID, newWeight) +} + +// InitiateValidatorWeightUpdate is a paid mutator transaction binding the contract method 0x66109669. +// +// Solidity: function initiateValidatorWeightUpdate(bytes32 validationID, uint64 newWeight) returns(uint64, bytes32) +func (_ValidatorManager *ValidatorManagerSession) InitiateValidatorWeightUpdate(validationID [32]byte, newWeight uint64) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitiateValidatorWeightUpdate(&_ValidatorManager.TransactOpts, validationID, newWeight) +} + +// InitiateValidatorWeightUpdate is a paid mutator transaction binding the contract method 0x66109669. +// +// Solidity: function initiateValidatorWeightUpdate(bytes32 validationID, uint64 newWeight) returns(uint64, bytes32) +func (_ValidatorManager *ValidatorManagerTransactorSession) InitiateValidatorWeightUpdate(validationID [32]byte, newWeight uint64) (*types.Transaction, error) { + return _ValidatorManager.Contract.InitiateValidatorWeightUpdate(&_ValidatorManager.TransactOpts, validationID, newWeight) +} + +// MigrateFromV1 is a paid mutator transaction binding the contract method 0x30ffe4d7. +// +// Solidity: function migrateFromV1(bytes32 validationID, uint32 receivedNonce) returns() +func (_ValidatorManager *ValidatorManagerTransactor) MigrateFromV1(opts *bind.TransactOpts, validationID [32]byte, receivedNonce uint32) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "migrateFromV1", validationID, receivedNonce) +} + +// MigrateFromV1 is a paid mutator transaction binding the contract method 0x30ffe4d7. +// +// Solidity: function migrateFromV1(bytes32 validationID, uint32 receivedNonce) returns() +func (_ValidatorManager *ValidatorManagerSession) MigrateFromV1(validationID [32]byte, receivedNonce uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.MigrateFromV1(&_ValidatorManager.TransactOpts, validationID, receivedNonce) +} + +// MigrateFromV1 is a paid mutator transaction binding the contract method 0x30ffe4d7. +// +// Solidity: function migrateFromV1(bytes32 validationID, uint32 receivedNonce) returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) MigrateFromV1(validationID [32]byte, receivedNonce uint32) (*types.Transaction, error) { + return _ValidatorManager.Contract.MigrateFromV1(&_ValidatorManager.TransactOpts, validationID, receivedNonce) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ValidatorManager *ValidatorManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ValidatorManager *ValidatorManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _ValidatorManager.Contract.RenounceOwnership(&_ValidatorManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ValidatorManager.Contract.RenounceOwnership(&_ValidatorManager.TransactOpts) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerTransactor) ResendRegisterValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "resendRegisterValidatorMessage", validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.Contract.ResendRegisterValidatorMessage(&_ValidatorManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.Contract.ResendRegisterValidatorMessage(&_ValidatorManager.TransactOpts, validationID) +} + +// ResendValidatorRemovalMessage is a paid mutator transaction binding the contract method 0x66edba73. +// +// Solidity: function resendValidatorRemovalMessage(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerTransactor) ResendValidatorRemovalMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "resendValidatorRemovalMessage", validationID) +} + +// ResendValidatorRemovalMessage is a paid mutator transaction binding the contract method 0x66edba73. +// +// Solidity: function resendValidatorRemovalMessage(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerSession) ResendValidatorRemovalMessage(validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.Contract.ResendValidatorRemovalMessage(&_ValidatorManager.TransactOpts, validationID) +} + +// ResendValidatorRemovalMessage is a paid mutator transaction binding the contract method 0x66edba73. +// +// Solidity: function resendValidatorRemovalMessage(bytes32 validationID) returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) ResendValidatorRemovalMessage(validationID [32]byte) (*types.Transaction, error) { + return _ValidatorManager.Contract.ResendValidatorRemovalMessage(&_ValidatorManager.TransactOpts, validationID) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ValidatorManager *ValidatorManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ValidatorManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ValidatorManager *ValidatorManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ValidatorManager.Contract.TransferOwnership(&_ValidatorManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ValidatorManager *ValidatorManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ValidatorManager.Contract.TransferOwnership(&_ValidatorManager.TransactOpts, newOwner) +} + +// ValidatorManagerCompletedValidatorRegistrationIterator is returned from FilterCompletedValidatorRegistration and is used to iterate over the raw logs and unpacked data for CompletedValidatorRegistration events raised by the ValidatorManager contract. +type ValidatorManagerCompletedValidatorRegistrationIterator struct { + Event *ValidatorManagerCompletedValidatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerCompletedValidatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerCompletedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerCompletedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerCompletedValidatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerCompletedValidatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerCompletedValidatorRegistration represents a CompletedValidatorRegistration event raised by the ValidatorManager contract. +type ValidatorManagerCompletedValidatorRegistration struct { + ValidationID [32]byte + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedValidatorRegistration is a free log retrieval operation binding the contract event 0x967ae87813a3b5f201dd9bcba778d457176eafe6f41facee1c718091d3952d06. +// +// Solidity: event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) FilterCompletedValidatorRegistration(opts *bind.FilterOpts, validationID [][32]byte) (*ValidatorManagerCompletedValidatorRegistrationIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "CompletedValidatorRegistration", validationIDRule) + if err != nil { + return nil, err + } + return &ValidatorManagerCompletedValidatorRegistrationIterator{contract: _ValidatorManager.contract, event: "CompletedValidatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchCompletedValidatorRegistration is a free log subscription operation binding the contract event 0x967ae87813a3b5f201dd9bcba778d457176eafe6f41facee1c718091d3952d06. +// +// Solidity: event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) WatchCompletedValidatorRegistration(opts *bind.WatchOpts, sink chan<- *ValidatorManagerCompletedValidatorRegistration, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "CompletedValidatorRegistration", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerCompletedValidatorRegistration) + if err := _ValidatorManager.contract.UnpackLog(event, "CompletedValidatorRegistration", 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 +} + +// ParseCompletedValidatorRegistration is a log parse operation binding the contract event 0x967ae87813a3b5f201dd9bcba778d457176eafe6f41facee1c718091d3952d06. +// +// Solidity: event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) ParseCompletedValidatorRegistration(log types.Log) (*ValidatorManagerCompletedValidatorRegistration, error) { + event := new(ValidatorManagerCompletedValidatorRegistration) + if err := _ValidatorManager.contract.UnpackLog(event, "CompletedValidatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerCompletedValidatorRemovalIterator is returned from FilterCompletedValidatorRemoval and is used to iterate over the raw logs and unpacked data for CompletedValidatorRemoval events raised by the ValidatorManager contract. +type ValidatorManagerCompletedValidatorRemovalIterator struct { + Event *ValidatorManagerCompletedValidatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerCompletedValidatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerCompletedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerCompletedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerCompletedValidatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerCompletedValidatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerCompletedValidatorRemoval represents a CompletedValidatorRemoval event raised by the ValidatorManager contract. +type ValidatorManagerCompletedValidatorRemoval struct { + ValidationID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedValidatorRemoval is a free log retrieval operation binding the contract event 0xafaccef7080649a725bc30a35359a257a4a27225be352875c80bdf6b5f04080c. +// +// Solidity: event CompletedValidatorRemoval(bytes32 indexed validationID) +func (_ValidatorManager *ValidatorManagerFilterer) FilterCompletedValidatorRemoval(opts *bind.FilterOpts, validationID [][32]byte) (*ValidatorManagerCompletedValidatorRemovalIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "CompletedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return &ValidatorManagerCompletedValidatorRemovalIterator{contract: _ValidatorManager.contract, event: "CompletedValidatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchCompletedValidatorRemoval is a free log subscription operation binding the contract event 0xafaccef7080649a725bc30a35359a257a4a27225be352875c80bdf6b5f04080c. +// +// Solidity: event CompletedValidatorRemoval(bytes32 indexed validationID) +func (_ValidatorManager *ValidatorManagerFilterer) WatchCompletedValidatorRemoval(opts *bind.WatchOpts, sink chan<- *ValidatorManagerCompletedValidatorRemoval, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "CompletedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerCompletedValidatorRemoval) + if err := _ValidatorManager.contract.UnpackLog(event, "CompletedValidatorRemoval", 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 +} + +// ParseCompletedValidatorRemoval is a log parse operation binding the contract event 0xafaccef7080649a725bc30a35359a257a4a27225be352875c80bdf6b5f04080c. +// +// Solidity: event CompletedValidatorRemoval(bytes32 indexed validationID) +func (_ValidatorManager *ValidatorManagerFilterer) ParseCompletedValidatorRemoval(log types.Log) (*ValidatorManagerCompletedValidatorRemoval, error) { + event := new(ValidatorManagerCompletedValidatorRemoval) + if err := _ValidatorManager.contract.UnpackLog(event, "CompletedValidatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerCompletedValidatorWeightUpdateIterator is returned from FilterCompletedValidatorWeightUpdate and is used to iterate over the raw logs and unpacked data for CompletedValidatorWeightUpdate events raised by the ValidatorManager contract. +type ValidatorManagerCompletedValidatorWeightUpdateIterator struct { + Event *ValidatorManagerCompletedValidatorWeightUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerCompletedValidatorWeightUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerCompletedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerCompletedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerCompletedValidatorWeightUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerCompletedValidatorWeightUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerCompletedValidatorWeightUpdate represents a CompletedValidatorWeightUpdate event raised by the ValidatorManager contract. +type ValidatorManagerCompletedValidatorWeightUpdate struct { + ValidationID [32]byte + Nonce uint64 + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedValidatorWeightUpdate is a free log retrieval operation binding the contract event 0xc917996591802ecedcfced71321d4bb5320f7dfbacf5477dffe1dbf8b8839ff9. +// +// Solidity: event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) FilterCompletedValidatorWeightUpdate(opts *bind.FilterOpts, validationID [][32]byte) (*ValidatorManagerCompletedValidatorWeightUpdateIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "CompletedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return &ValidatorManagerCompletedValidatorWeightUpdateIterator{contract: _ValidatorManager.contract, event: "CompletedValidatorWeightUpdate", logs: logs, sub: sub}, nil +} + +// WatchCompletedValidatorWeightUpdate is a free log subscription operation binding the contract event 0xc917996591802ecedcfced71321d4bb5320f7dfbacf5477dffe1dbf8b8839ff9. +// +// Solidity: event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) WatchCompletedValidatorWeightUpdate(opts *bind.WatchOpts, sink chan<- *ValidatorManagerCompletedValidatorWeightUpdate, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "CompletedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerCompletedValidatorWeightUpdate) + if err := _ValidatorManager.contract.UnpackLog(event, "CompletedValidatorWeightUpdate", 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 +} + +// ParseCompletedValidatorWeightUpdate is a log parse operation binding the contract event 0xc917996591802ecedcfced71321d4bb5320f7dfbacf5477dffe1dbf8b8839ff9. +// +// Solidity: event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) ParseCompletedValidatorWeightUpdate(log types.Log) (*ValidatorManagerCompletedValidatorWeightUpdate, error) { + event := new(ValidatorManagerCompletedValidatorWeightUpdate) + if err := _ValidatorManager.contract.UnpackLog(event, "CompletedValidatorWeightUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ValidatorManager contract. +type ValidatorManagerInitializedIterator struct { + Event *ValidatorManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerInitialized represents a Initialized event raised by the ValidatorManager contract. +type ValidatorManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ValidatorManager *ValidatorManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ValidatorManagerInitializedIterator, error) { + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ValidatorManagerInitializedIterator{contract: _ValidatorManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ValidatorManager *ValidatorManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ValidatorManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerInitialized) + if err := _ValidatorManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ValidatorManager *ValidatorManagerFilterer) ParseInitialized(log types.Log) (*ValidatorManagerInitialized, error) { + event := new(ValidatorManagerInitialized) + if err := _ValidatorManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerInitiatedValidatorRegistrationIterator is returned from FilterInitiatedValidatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedValidatorRegistration events raised by the ValidatorManager contract. +type ValidatorManagerInitiatedValidatorRegistrationIterator struct { + Event *ValidatorManagerInitiatedValidatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerInitiatedValidatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitiatedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitiatedValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerInitiatedValidatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerInitiatedValidatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerInitiatedValidatorRegistration represents a InitiatedValidatorRegistration event raised by the ValidatorManager contract. +type ValidatorManagerInitiatedValidatorRegistration struct { + ValidationID [32]byte + NodeID [20]byte + RegistrationMessageID [32]byte + RegistrationExpiry uint64 + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedValidatorRegistration is a free log retrieval operation binding the contract event 0x5881be437bdcb008bfa5f20e32d3e335ccf8ab90ef2818852a251625260af35d. +// +// Solidity: event InitiatedValidatorRegistration(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 registrationMessageID, uint64 registrationExpiry, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) FilterInitiatedValidatorRegistration(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][20]byte) (*ValidatorManagerInitiatedValidatorRegistrationIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "InitiatedValidatorRegistration", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return &ValidatorManagerInitiatedValidatorRegistrationIterator{contract: _ValidatorManager.contract, event: "InitiatedValidatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedValidatorRegistration is a free log subscription operation binding the contract event 0x5881be437bdcb008bfa5f20e32d3e335ccf8ab90ef2818852a251625260af35d. +// +// Solidity: event InitiatedValidatorRegistration(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 registrationMessageID, uint64 registrationExpiry, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) WatchInitiatedValidatorRegistration(opts *bind.WatchOpts, sink chan<- *ValidatorManagerInitiatedValidatorRegistration, validationID [][32]byte, nodeID [][20]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "InitiatedValidatorRegistration", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerInitiatedValidatorRegistration) + if err := _ValidatorManager.contract.UnpackLog(event, "InitiatedValidatorRegistration", 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 +} + +// ParseInitiatedValidatorRegistration is a log parse operation binding the contract event 0x5881be437bdcb008bfa5f20e32d3e335ccf8ab90ef2818852a251625260af35d. +// +// Solidity: event InitiatedValidatorRegistration(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 registrationMessageID, uint64 registrationExpiry, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) ParseInitiatedValidatorRegistration(log types.Log) (*ValidatorManagerInitiatedValidatorRegistration, error) { + event := new(ValidatorManagerInitiatedValidatorRegistration) + if err := _ValidatorManager.contract.UnpackLog(event, "InitiatedValidatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerInitiatedValidatorRemovalIterator is returned from FilterInitiatedValidatorRemoval and is used to iterate over the raw logs and unpacked data for InitiatedValidatorRemoval events raised by the ValidatorManager contract. +type ValidatorManagerInitiatedValidatorRemovalIterator struct { + Event *ValidatorManagerInitiatedValidatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerInitiatedValidatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitiatedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitiatedValidatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerInitiatedValidatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerInitiatedValidatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerInitiatedValidatorRemoval represents a InitiatedValidatorRemoval event raised by the ValidatorManager contract. +type ValidatorManagerInitiatedValidatorRemoval struct { + ValidationID [32]byte + ValidatorWeightMessageID [32]byte + Weight uint64 + EndTime uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedValidatorRemoval is a free log retrieval operation binding the contract event 0xbae388a94e7f18411fe57098f12f418b8e1a8273e0532a90188a3a059b897273. +// +// Solidity: event InitiatedValidatorRemoval(bytes32 indexed validationID, bytes32 validatorWeightMessageID, uint64 weight, uint64 endTime) +func (_ValidatorManager *ValidatorManagerFilterer) FilterInitiatedValidatorRemoval(opts *bind.FilterOpts, validationID [][32]byte) (*ValidatorManagerInitiatedValidatorRemovalIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "InitiatedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return &ValidatorManagerInitiatedValidatorRemovalIterator{contract: _ValidatorManager.contract, event: "InitiatedValidatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchInitiatedValidatorRemoval is a free log subscription operation binding the contract event 0xbae388a94e7f18411fe57098f12f418b8e1a8273e0532a90188a3a059b897273. +// +// Solidity: event InitiatedValidatorRemoval(bytes32 indexed validationID, bytes32 validatorWeightMessageID, uint64 weight, uint64 endTime) +func (_ValidatorManager *ValidatorManagerFilterer) WatchInitiatedValidatorRemoval(opts *bind.WatchOpts, sink chan<- *ValidatorManagerInitiatedValidatorRemoval, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "InitiatedValidatorRemoval", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerInitiatedValidatorRemoval) + if err := _ValidatorManager.contract.UnpackLog(event, "InitiatedValidatorRemoval", 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 +} + +// ParseInitiatedValidatorRemoval is a log parse operation binding the contract event 0xbae388a94e7f18411fe57098f12f418b8e1a8273e0532a90188a3a059b897273. +// +// Solidity: event InitiatedValidatorRemoval(bytes32 indexed validationID, bytes32 validatorWeightMessageID, uint64 weight, uint64 endTime) +func (_ValidatorManager *ValidatorManagerFilterer) ParseInitiatedValidatorRemoval(log types.Log) (*ValidatorManagerInitiatedValidatorRemoval, error) { + event := new(ValidatorManagerInitiatedValidatorRemoval) + if err := _ValidatorManager.contract.UnpackLog(event, "InitiatedValidatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerInitiatedValidatorWeightUpdateIterator is returned from FilterInitiatedValidatorWeightUpdate and is used to iterate over the raw logs and unpacked data for InitiatedValidatorWeightUpdate events raised by the ValidatorManager contract. +type ValidatorManagerInitiatedValidatorWeightUpdateIterator struct { + Event *ValidatorManagerInitiatedValidatorWeightUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerInitiatedValidatorWeightUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitiatedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerInitiatedValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerInitiatedValidatorWeightUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerInitiatedValidatorWeightUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerInitiatedValidatorWeightUpdate represents a InitiatedValidatorWeightUpdate event raised by the ValidatorManager contract. +type ValidatorManagerInitiatedValidatorWeightUpdate struct { + ValidationID [32]byte + Nonce uint64 + WeightUpdateMessageID [32]byte + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedValidatorWeightUpdate is a free log retrieval operation binding the contract event 0x6e350dd49b060d87f297206fd309234ed43156d890ced0f139ecf704310481d3. +// +// Solidity: event InitiatedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) FilterInitiatedValidatorWeightUpdate(opts *bind.FilterOpts, validationID [][32]byte) (*ValidatorManagerInitiatedValidatorWeightUpdateIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "InitiatedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return &ValidatorManagerInitiatedValidatorWeightUpdateIterator{contract: _ValidatorManager.contract, event: "InitiatedValidatorWeightUpdate", logs: logs, sub: sub}, nil +} + +// WatchInitiatedValidatorWeightUpdate is a free log subscription operation binding the contract event 0x6e350dd49b060d87f297206fd309234ed43156d890ced0f139ecf704310481d3. +// +// Solidity: event InitiatedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) WatchInitiatedValidatorWeightUpdate(opts *bind.WatchOpts, sink chan<- *ValidatorManagerInitiatedValidatorWeightUpdate, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "InitiatedValidatorWeightUpdate", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerInitiatedValidatorWeightUpdate) + if err := _ValidatorManager.contract.UnpackLog(event, "InitiatedValidatorWeightUpdate", 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 +} + +// ParseInitiatedValidatorWeightUpdate is a log parse operation binding the contract event 0x6e350dd49b060d87f297206fd309234ed43156d890ced0f139ecf704310481d3. +// +// Solidity: event InitiatedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) ParseInitiatedValidatorWeightUpdate(log types.Log) (*ValidatorManagerInitiatedValidatorWeightUpdate, error) { + event := new(ValidatorManagerInitiatedValidatorWeightUpdate) + if err := _ValidatorManager.contract.UnpackLog(event, "InitiatedValidatorWeightUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ValidatorManager contract. +type ValidatorManagerOwnershipTransferredIterator struct { + Event *ValidatorManagerOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerOwnershipTransferred represents a OwnershipTransferred event raised by the ValidatorManager contract. +type ValidatorManagerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ValidatorManager *ValidatorManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ValidatorManagerOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ValidatorManagerOwnershipTransferredIterator{contract: _ValidatorManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ValidatorManager *ValidatorManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ValidatorManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerOwnershipTransferred) + if err := _ValidatorManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ValidatorManager *ValidatorManagerFilterer) ParseOwnershipTransferred(log types.Log) (*ValidatorManagerOwnershipTransferred, error) { + event := new(ValidatorManagerOwnershipTransferred) + if err := _ValidatorManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorManagerRegisteredInitialValidatorIterator is returned from FilterRegisteredInitialValidator and is used to iterate over the raw logs and unpacked data for RegisteredInitialValidator events raised by the ValidatorManager contract. +type ValidatorManagerRegisteredInitialValidatorIterator struct { + Event *ValidatorManagerRegisteredInitialValidator // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ValidatorManagerRegisteredInitialValidatorIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerRegisteredInitialValidator) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ValidatorManagerRegisteredInitialValidator) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ValidatorManagerRegisteredInitialValidatorIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ValidatorManagerRegisteredInitialValidatorIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ValidatorManagerRegisteredInitialValidator represents a RegisteredInitialValidator event raised by the ValidatorManager contract. +type ValidatorManagerRegisteredInitialValidator struct { + ValidationID [32]byte + NodeID [20]byte + SubnetID [32]byte + Weight uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRegisteredInitialValidator is a free log retrieval operation binding the contract event 0x070e0f6540afd612d613b71036a6d45f8c5fa97770a7e2d55663d75474ce0c0d. +// +// Solidity: event RegisteredInitialValidator(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 indexed subnetID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) FilterRegisteredInitialValidator(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][20]byte, subnetID [][32]byte) (*ValidatorManagerRegisteredInitialValidatorIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var subnetIDRule []interface{} + for _, subnetIDItem := range subnetID { + subnetIDRule = append(subnetIDRule, subnetIDItem) + } + + logs, sub, err := _ValidatorManager.contract.FilterLogs(opts, "RegisteredInitialValidator", validationIDRule, nodeIDRule, subnetIDRule) + if err != nil { + return nil, err + } + return &ValidatorManagerRegisteredInitialValidatorIterator{contract: _ValidatorManager.contract, event: "RegisteredInitialValidator", logs: logs, sub: sub}, nil +} + +// WatchRegisteredInitialValidator is a free log subscription operation binding the contract event 0x070e0f6540afd612d613b71036a6d45f8c5fa97770a7e2d55663d75474ce0c0d. +// +// Solidity: event RegisteredInitialValidator(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 indexed subnetID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) WatchRegisteredInitialValidator(opts *bind.WatchOpts, sink chan<- *ValidatorManagerRegisteredInitialValidator, validationID [][32]byte, nodeID [][20]byte, subnetID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var subnetIDRule []interface{} + for _, subnetIDItem := range subnetID { + subnetIDRule = append(subnetIDRule, subnetIDItem) + } + + logs, sub, err := _ValidatorManager.contract.WatchLogs(opts, "RegisteredInitialValidator", validationIDRule, nodeIDRule, subnetIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ValidatorManagerRegisteredInitialValidator) + if err := _ValidatorManager.contract.UnpackLog(event, "RegisteredInitialValidator", 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 +} + +// ParseRegisteredInitialValidator is a log parse operation binding the contract event 0x070e0f6540afd612d613b71036a6d45f8c5fa97770a7e2d55663d75474ce0c0d. +// +// Solidity: event RegisteredInitialValidator(bytes32 indexed validationID, bytes20 indexed nodeID, bytes32 indexed subnetID, uint64 weight) +func (_ValidatorManager *ValidatorManagerFilterer) ParseRegisteredInitialValidator(log types.Log) (*ValidatorManagerRegisteredInitialValidator, error) { + event := new(ValidatorManagerRegisteredInitialValidator) + if err := _ValidatorManager.contract.UnpackLog(event, "RegisteredInitialValidator", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ValidatorMessagesMetaData contains all meta data concerning the ValidatorMessages contract. +var ValidatorMessagesMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"InvalidBLSPublicKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"InvalidCodecID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"actual\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageType\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"validatorManagerAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structInitialValidator[]\",\"name\":\"initialValidators\",\"type\":\"tuple[]\"}],\"internalType\":\"structConversionData\",\"name\":\"conversionData\",\"type\":\"tuple\"}],\"name\":\"packConversionData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"registered\",\"type\":\"bool\"}],\"name\":\"packL1ValidatorRegistrationMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"name\":\"packL1ValidatorWeightMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structValidatorMessages.ValidationPeriod\",\"name\":\"validationPeriod\",\"type\":\"tuple\"}],\"name\":\"packRegisterL1ValidatorMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"conversionID\",\"type\":\"bytes32\"}],\"name\":\"packSubnetToL1ConversionMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"uptime\",\"type\":\"uint64\"}],\"name\":\"packValidationUptimeMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackL1ValidatorRegistrationMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackL1ValidatorWeightMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackRegisterL1ValidatorMessage\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"subnetID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"nodeID\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"blsPublicKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"registrationExpiry\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"remainingBalanceOwner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"threshold\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"internalType\":\"structPChainOwner\",\"name\":\"disableOwner\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structValidatorMessages.ValidationPeriod\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackSubnetToL1ConversionMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"unpackValidationUptimeMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x61217b610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100b1575f3560e01c8063854a893f11610079578063854a893f146101b257806387418b8e1461020f5780639b83546514610222578063a699c13514610242578063e1d68f3014610255578063eb97ce5114610268575f80fd5b8063021de88f146100b5578063088c2463146100e25780634d8478841461011257806350782b0f146101335780637f7c427a1461016b575b5f80fd5b6100c86100c33660046118a9565b610289565b604080519283529015156020830152015b60405180910390f35b6100f56100f03660046118a9565b61044a565b604080519283526001600160401b039091166020830152016100d9565b6101256101203660046118a9565b61063b565b6040519081526020016100d9565b6101466101413660046118a9565b6107c8565b604080519384526001600160401b0392831660208501529116908201526060016100d9565b6101a56101793660046118e2565b604080515f60208201819052602282015260268082019390935281518082039093018352604601905290565b6040516100d99190611946565b6101a56101c036600461197a565b604080515f6020820152600360e01b602282015260268101949094526001600160c01b031960c093841b811660468601529190921b16604e830152805180830360360181526056909201905290565b6101a561021d3660046119eb565b610a1e565b6102356102303660046118a9565b610b60565b6040516100d99190611bb4565b6101a5610250366004611c6b565b6114ab565b6101a5610263366004611c9d565b6114ef565b61027b610276366004611d80565b611525565b6040516100d9929190611e7c565b5f8082516027146102c457825160405163cc92daa160e01b815263ffffffff9091166004820152602760248201526044015b60405180910390fd5b5f805b6002811015610313576102db816001611ea8565b6102e6906008611ebb565b61ffff168582815181106102fc576102fc611ed2565b016020015160f81c901b91909117906001016102c7565b5061ffff81161561033d5760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561039857610354816003611ea8565b61035f906008611ebb565b63ffffffff1686610371836002611ee6565b8151811061038157610381611ed2565b016020015160f81c901b9190911790600101610340565b5063ffffffff81166002146103c057604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015610415576103d781601f611ea8565b6103e2906008611ebb565b876103ee836006611ee6565b815181106103fe576103fe611ed2565b016020015160f81c901b91909117906001016103c3565b505f8660268151811061042a5761042a611ed2565b016020015191976001600160f81b03199092161515965090945050505050565b5f808251602e1461048057825160405163cc92daa160e01b815263ffffffff9091166004820152602e60248201526044016102bb565b5f805b60028110156104cf57610497816001611ea8565b6104a2906008611ebb565b61ffff168582815181106104b8576104b8611ed2565b016020015160f81c901b9190911790600101610483565b5061ffff8116156104f95760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561055457610510816003611ea8565b61051b906008611ebb565b63ffffffff168661052d836002611ee6565b8151811061053d5761053d611ed2565b016020015160f81c901b91909117906001016104fc565b5063ffffffff81161561057a57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156105cf5761059181601f611ea8565b61059c906008611ebb565b876105a8836006611ee6565b815181106105b8576105b8611ed2565b016020015160f81c901b919091179060010161057d565b505f805b600881101561062e576105e7816007611ea8565b6105f2906008611ebb565b6001600160401b031688610607836026611ee6565b8151811061061757610617611ed2565b016020015160f81c901b91909117906001016105d3565b5090969095509350505050565b5f815160261461067057815160405163cc92daa160e01b815263ffffffff9091166004820152602660248201526044016102bb565b5f805b60028110156106bf57610687816001611ea8565b610692906008611ebb565b61ffff168482815181106106a8576106a8611ed2565b016020015160f81c901b9190911790600101610673565b5061ffff8116156106e95760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b600481101561074457610700816003611ea8565b61070b906008611ebb565b63ffffffff168561071d836002611ee6565b8151811061072d5761072d611ed2565b016020015160f81c901b91909117906001016106ec565b5063ffffffff81161561076a57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156107bf5761078181601f611ea8565b61078c906008611ebb565b86610798836006611ee6565b815181106107a8576107a8611ed2565b016020015160f81c901b919091179060010161076d565b50949350505050565b5f805f83516036146107ff57835160405163cc92daa160e01b815263ffffffff9091166004820152603660248201526044016102bb565b5f805b600281101561084e57610816816001611ea8565b610821906008611ebb565b61ffff1686828151811061083757610837611ed2565b016020015160f81c901b9190911790600101610802565b5061ffff8116156108785760405163407b587360e01b815261ffff821660048201526024016102bb565b5f805b60048110156108d35761088f816003611ea8565b61089a906008611ebb565b63ffffffff16876108ac836002611ee6565b815181106108bc576108bc611ed2565b016020015160f81c901b919091179060010161087b565b5063ffffffff81166003146108fb57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156109505761091281601f611ea8565b61091d906008611ebb565b88610929836006611ee6565b8151811061093957610939611ed2565b016020015160f81c901b91909117906001016108fe565b505f805b60088110156109af57610968816007611ea8565b610973906008611ebb565b6001600160401b031689610988836026611ee6565b8151811061099857610998611ed2565b016020015160f81c901b9190911790600101610954565b505f805b6008811015610a0e576109c7816007611ea8565b6109d2906008611ebb565b6001600160401b03168a6109e783602e611ee6565b815181106109f7576109f7611ed2565b016020015160f81c901b91909117906001016109b3565b5091989097509095509350505050565b80516020808301516040808501516060868101515192515f95810186905260228101969096526042860193909352600560e21b60628601526bffffffffffffffffffffffff1990831b16606685015260e01b6001600160e01b031916607a84015291607e0160405160208183030381529060405290505f5b836060015151811015610b59578184606001518281518110610aba57610aba611ed2565b60200260200101515f01515185606001518381518110610adc57610adc611ed2565b60200260200101515f015186606001518481518110610afd57610afd611ed2565b60200260200101516020015187606001518581518110610b1f57610b1f611ed2565b602002602001015160400151604051602001610b3f959493929190611ef9565b60408051601f198184030181529190529150600101610a96565b5092915050565b610b68611712565b5f610b71611712565b5f805b6002811015610bcf57610b88816001611ea8565b610b93906008611ebb565b61ffff1686610ba863ffffffff871684611ee6565b81518110610bb857610bb8611ed2565b016020015160f81c901b9190911790600101610b74565b5061ffff811615610bf95760405163407b587360e01b815261ffff821660048201526024016102bb565b610c04600284611f72565b9250505f805b6004811015610c6957610c1e816003611ea8565b610c29906008611ebb565b63ffffffff16868563ffffffff1683610c429190611ee6565b81518110610c5257610c52611ed2565b016020015160f81c901b9190911790600101610c0a565b5063ffffffff8116600114610c9157604051635b60892f60e01b815260040160405180910390fd5b610c9c600484611f72565b9250505f805b6020811015610cf957610cb681601f611ea8565b610cc1906008611ebb565b86610cd263ffffffff871684611ee6565b81518110610ce257610ce2611ed2565b016020015160f81c901b9190911790600101610ca2565b50808252610d08602084611f72565b9250505f805b6004811015610d6d57610d22816003611ea8565b610d2d906008611ebb565b63ffffffff16868563ffffffff1683610d469190611ee6565b81518110610d5657610d56611ed2565b016020015160f81c901b9190911790600101610d0e565b50610d79600484611f72565b92505f8163ffffffff166001600160401b03811115610d9a57610d9a61176c565b6040519080825280601f01601f191660200182016040528015610dc4576020820181803683370190505b5090505f5b8263ffffffff16811015610e335786610de863ffffffff871683611ee6565b81518110610df857610df8611ed2565b602001015160f81c60f81b828281518110610e1557610e15611ed2565b60200101906001600160f81b03191690815f1a905350600101610dc9565b5060208301819052610e458285611f72565b604080516030808252606082019092529195505f92506020820181803683370190505090505f5b6030811015610ed15786610e8663ffffffff871683611ee6565b81518110610e9657610e96611ed2565b602001015160f81c60f81b828281518110610eb357610eb3611ed2565b60200101906001600160f81b03191690815f1a905350600101610e6c565b5060408301819052610ee4603085611f72565b9350505f805b6008811015610f4a57610efe816007611ea8565b610f09906008611ebb565b6001600160401b031687610f2363ffffffff881684611ee6565b81518110610f3357610f33611ed2565b016020015160f81c901b9190911790600101610eea565b506001600160401b0381166060840152610f65600885611f72565b9350505f805f5b6004811015610fcb57610f80816003611ea8565b610f8b906008611ebb565b63ffffffff16888763ffffffff1683610fa49190611ee6565b81518110610fb457610fb4611ed2565b016020015160f81c901b9190911790600101610f6c565b50610fd7600486611f72565b94505f5b600481101561103a57610fef816003611ea8565b610ffa906008611ebb565b63ffffffff16888763ffffffff16836110139190611ee6565b8151811061102357611023611ed2565b016020015160f81c901b9290921791600101610fdb565b50611046600486611f72565b94505f8263ffffffff166001600160401b038111156110675761106761176c565b604051908082528060200260200182016040528015611090578160200160208202803683370190505b5090505f5b8363ffffffff16811015611178576040805160148082528183019092525f916020820181803683370190505090505f5b601481101561112a578a6110df63ffffffff8b1683611ee6565b815181106110ef576110ef611ed2565b602001015160f81c60f81b82828151811061110c5761110c611ed2565b60200101906001600160f81b03191690815f1a9053506001016110c5565b505f601482015190508084848151811061114657611146611ed2565b6001600160a01b039092166020928302919091019091015261116960148a611f72565b98505050806001019050611095565b506040805180820190915263ffffffff9092168252602082015260808401525f80805b60048110156111fa576111af816003611ea8565b6111ba906008611ebb565b63ffffffff16898863ffffffff16836111d39190611ee6565b815181106111e3576111e3611ed2565b016020015160f81c901b919091179060010161119b565b50611206600487611f72565b95505f5b60048110156112695761121e816003611ea8565b611229906008611ebb565b63ffffffff16898863ffffffff16836112429190611ee6565b8151811061125257611252611ed2565b016020015160f81c901b929092179160010161120a565b50611275600487611f72565b95505f8263ffffffff166001600160401b038111156112965761129661176c565b6040519080825280602002602001820160405280156112bf578160200160208202803683370190505b5090505f5b8363ffffffff168110156113a7576040805160148082528183019092525f916020820181803683370190505090505f5b6014811015611359578b61130e63ffffffff8c1683611ee6565b8151811061131e5761131e611ed2565b602001015160f81c60f81b82828151811061133b5761133b611ed2565b60200101906001600160f81b03191690815f1a9053506001016112f4565b505f601482015190508084848151811061137557611375611ed2565b6001600160a01b039092166020928302919091019091015261139860148b611f72565b995050508060010190506112c4565b506040805180820190915263ffffffff9092168252602082015260a08501525f6113d18284611f72565b6113dc906014611f8f565b6113e785607a611f72565b6113f19190611f72565b90508063ffffffff1688511461142d57875160405163cc92daa160e01b815263ffffffff918216600482015290821660248201526044016102bb565b5f805b600881101561149057611444816007611ea8565b61144f906008611ebb565b6001600160401b03168a61146963ffffffff8b1684611ee6565b8151811061147957611479611ed2565b016020015160f81c901b9190911790600101611430565b506001600160401b031660c086015250929695505050505050565b6040515f6020820152600160e11b60228201526026810183905281151560f81b60468201526060906047015b60405160208183030381529060405290505b92915050565b6040515f602082018190526022820152602681018390526001600160c01b031960c083901b166046820152606090604e016114d7565b5f606082604001515160301461154e5760405163180ffa0d60e01b815260040160405180910390fd5b82516020808501518051604080880151606089015160808a01518051908701515193515f9861158f988a986001989297929690959094909390929101611fb7565b60405160208183030381529060405290505f5b84608001516020015151811015611601578185608001516020015182815181106115ce576115ce611ed2565b60200260200101516040516020016115e7929190612071565b60408051601f1981840301815291905291506001016115a2565b5060a08401518051602091820151516040516116219385939291016120a7565b60405160208183030381529060405290505f5b8460a00151602001515181101561169357818560a0015160200151828151811061166057611660611ed2565b6020026020010151604051602001611679929190612071565b60408051601f198184030181529190529150600101611634565b5060c08401516040516116aa9183916020016120e2565b60405160208183030381529060405290506002816040516116cb9190612113565b602060405180830381855afa1580156116e6573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611709919061212e565b94909350915050565b6040805160e0810182525f808252606060208084018290528385018290528184018390528451808601865283815280820183905260808501528451808601909552918452908301529060a082019081525f60209091015290565b634e487b7160e01b5f52604160045260245ffd5b604051608081016001600160401b03811182821017156117a2576117a261176c565b60405290565b604051606081016001600160401b03811182821017156117a2576117a261176c565b604080519081016001600160401b03811182821017156117a2576117a261176c565b60405160e081016001600160401b03811182821017156117a2576117a261176c565b604051601f8201601f191681016001600160401b03811182821017156118365761183661176c565b604052919050565b5f82601f83011261184d575f80fd5b81356001600160401b038111156118665761186661176c565b611879601f8201601f191660200161180e565b81815284602083860101111561188d575f80fd5b816020850160208301375f918101602001919091529392505050565b5f602082840312156118b9575f80fd5b81356001600160401b038111156118ce575f80fd5b6118da8482850161183e565b949350505050565b5f602082840312156118f2575f80fd5b5035919050565b5f5b838110156119135781810151838201526020016118fb565b50505f910152565b5f81518084526119328160208601602086016118f9565b601f01601f19169290920160200192915050565b602081525f611958602083018461191b565b9392505050565b80356001600160401b0381168114611975575f80fd5b919050565b5f805f6060848603121561198c575f80fd5b8335925061199c6020850161195f565b91506119aa6040850161195f565b90509250925092565b80356001600160a01b0381168114611975575f80fd5b5f6001600160401b038211156119e1576119e161176c565b5060051b60200190565b5f60208083850312156119fc575f80fd5b82356001600160401b0380821115611a12575f80fd5b9084019060808287031215611a25575f80fd5b611a2d611780565b823581528383013584820152611a45604084016119b3565b604082015260608084013583811115611a5c575f80fd5b80850194505087601f850112611a70575f80fd5b8335611a83611a7e826119c9565b61180e565b81815260059190911b8501860190868101908a831115611aa1575f80fd5b8787015b83811015611b3a57803587811115611abb575f80fd5b8801808d03601f1901861315611acf575f80fd5b611ad76117a8565b8a82013589811115611ae7575f80fd5b611af58f8d8386010161183e565b825250604082013589811115611b09575f80fd5b611b178f8d8386010161183e565b8c83015250611b2787830161195f565b6040820152845250918801918801611aa5565b506060850152509198975050505050505050565b5f6040830163ffffffff8351168452602080840151604060208701528281518085526060880191506020830194505f92505b80831015611ba95784516001600160a01b03168252938301936001929092019190830190611b80565b509695505050505050565b60208152815160208201525f602083015160e06040840152611bda61010084018261191b565b90506040840151601f1980858403016060860152611bf8838361191b565b92506001600160401b03606087015116608086015260808601519150808584030160a0860152611c288383611b4e565b925060a08601519150808584030160c086015250611c468282611b4e565b91505060c0840151611c6360e08501826001600160401b03169052565b509392505050565b5f8060408385031215611c7c575f80fd5b8235915060208301358015158114611c92575f80fd5b809150509250929050565b5f8060408385031215611cae575f80fd5b82359150611cbe6020840161195f565b90509250929050565b5f60408284031215611cd7575f80fd5b611cdf6117ca565b9050813563ffffffff81168114611cf4575f80fd5b81526020828101356001600160401b03811115611d0f575f80fd5b8301601f81018513611d1f575f80fd5b8035611d2d611a7e826119c9565b81815260059190911b82018301908381019087831115611d4b575f80fd5b928401925b82841015611d7057611d61846119b3565b82529284019290840190611d50565b8085870152505050505092915050565b5f60208284031215611d90575f80fd5b81356001600160401b0380821115611da6575f80fd5b9083019060e08286031215611db9575f80fd5b611dc16117ec565b82358152602083013582811115611dd6575f80fd5b611de28782860161183e565b602083015250604083013582811115611df9575f80fd5b611e058782860161183e565b604083015250611e176060840161195f565b6060820152608083013582811115611e2d575f80fd5b611e3987828601611cc7565b60808301525060a083013582811115611e50575f80fd5b611e5c87828601611cc7565b60a083015250611e6e60c0840161195f565b60c082015295945050505050565b828152604060208201525f6118da604083018461191b565b634e487b7160e01b5f52601160045260245ffd5b818103818111156114e9576114e9611e94565b80820281158282048414176114e9576114e9611e94565b634e487b7160e01b5f52603260045260245ffd5b808201808211156114e9576114e9611e94565b5f8651611f0a818460208b016118f9565b60e087901b6001600160e01b0319169083019081528551611f32816004840160208a016118f9565b8551910190611f488160048401602089016118f9565b60c09490941b6001600160c01b031916600491909401908101939093525050600c01949350505050565b63ffffffff818116838216019080821115610b5957610b59611e94565b63ffffffff818116838216028082169190828114611faf57611faf611e94565b505092915050565b61ffff60f01b8a60f01b1681525f63ffffffff60e01b808b60e01b166002840152896006840152808960e01b166026840152508651611ffd81602a850160208b016118f9565b86519083019061201481602a840160208b016118f9565b60c087901b6001600160c01b031916602a9290910191820152612046603282018660e01b6001600160e01b0319169052565b61205f603682018560e01b6001600160e01b0319169052565b603a019b9a5050505050505050505050565b5f83516120828184602088016118f9565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b5f84516120b88184602089016118f9565b6001600160e01b031960e095861b8116919093019081529290931b16600482015260080192915050565b5f83516120f38184602088016118f9565b60c09390931b6001600160c01b0319169190920190815260080192915050565b5f82516121248184602087016118f9565b9190910192915050565b5f6020828403121561213e575f80fd5b505191905056fea26469706673582212204c79a1f4a6f5c66db9481c372405f40b1b5d511151053a9518bb9ce8f1032e4164736f6c63430008190033", +} + +// ValidatorMessagesABI is the input ABI used to generate the binding from. +// Deprecated: Use ValidatorMessagesMetaData.ABI instead. +var ValidatorMessagesABI = ValidatorMessagesMetaData.ABI + +// ValidatorMessagesBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ValidatorMessagesMetaData.Bin instead. +var ValidatorMessagesBin = ValidatorMessagesMetaData.Bin + +// DeployValidatorMessages deploys a new Ethereum contract, binding an instance of ValidatorMessages to it. +func DeployValidatorMessages(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ValidatorMessages, error) { + parsed, err := ValidatorMessagesMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ValidatorMessagesBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ValidatorMessages{ValidatorMessagesCaller: ValidatorMessagesCaller{contract: contract}, ValidatorMessagesTransactor: ValidatorMessagesTransactor{contract: contract}, ValidatorMessagesFilterer: ValidatorMessagesFilterer{contract: contract}}, nil +} + +// ValidatorMessages is an auto generated Go binding around an Ethereum contract. +type ValidatorMessages struct { + ValidatorMessagesCaller // Read-only binding to the contract + ValidatorMessagesTransactor // Write-only binding to the contract + ValidatorMessagesFilterer // Log filterer for contract events +} + +// ValidatorMessagesCaller is an auto generated read-only Go binding around an Ethereum contract. +type ValidatorMessagesCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ValidatorMessagesTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ValidatorMessagesFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ValidatorMessagesSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ValidatorMessagesSession struct { + Contract *ValidatorMessages // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorMessagesCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ValidatorMessagesCallerSession struct { + Contract *ValidatorMessagesCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ValidatorMessagesTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ValidatorMessagesTransactorSession struct { + Contract *ValidatorMessagesTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ValidatorMessagesRaw is an auto generated low-level Go binding around an Ethereum contract. +type ValidatorMessagesRaw struct { + Contract *ValidatorMessages // Generic contract binding to access the raw methods on +} + +// ValidatorMessagesCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ValidatorMessagesCallerRaw struct { + Contract *ValidatorMessagesCaller // Generic read-only contract binding to access the raw methods on +} + +// ValidatorMessagesTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ValidatorMessagesTransactorRaw struct { + Contract *ValidatorMessagesTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewValidatorMessages creates a new instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessages(address common.Address, backend bind.ContractBackend) (*ValidatorMessages, error) { + contract, err := bindValidatorMessages(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ValidatorMessages{ValidatorMessagesCaller: ValidatorMessagesCaller{contract: contract}, ValidatorMessagesTransactor: ValidatorMessagesTransactor{contract: contract}, ValidatorMessagesFilterer: ValidatorMessagesFilterer{contract: contract}}, nil +} + +// NewValidatorMessagesCaller creates a new read-only instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesCaller(address common.Address, caller bind.ContractCaller) (*ValidatorMessagesCaller, error) { + contract, err := bindValidatorMessages(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ValidatorMessagesCaller{contract: contract}, nil +} + +// NewValidatorMessagesTransactor creates a new write-only instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorMessagesTransactor, error) { + contract, err := bindValidatorMessages(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ValidatorMessagesTransactor{contract: contract}, nil +} + +// NewValidatorMessagesFilterer creates a new log filterer instance of ValidatorMessages, bound to a specific deployed contract. +func NewValidatorMessagesFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorMessagesFilterer, error) { + contract, err := bindValidatorMessages(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ValidatorMessagesFilterer{contract: contract}, nil +} + +// bindValidatorMessages binds a generic wrapper to an already deployed contract. +func bindValidatorMessages(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ValidatorMessagesMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorMessages *ValidatorMessagesRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorMessages.Contract.ValidatorMessagesCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorMessages *ValidatorMessagesRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorMessages.Contract.ValidatorMessagesTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorMessages *ValidatorMessagesRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorMessages.Contract.ValidatorMessagesTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ValidatorMessages *ValidatorMessagesCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ValidatorMessages.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ValidatorMessages *ValidatorMessagesTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ValidatorMessages.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ValidatorMessages *ValidatorMessagesTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ValidatorMessages.Contract.contract.Transact(opts, method, params...) +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackConversionData(opts *bind.CallOpts, conversionData ConversionData) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packConversionData", conversionData) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackConversionData(conversionData ConversionData) ([]byte, error) { + return _ValidatorMessages.Contract.PackConversionData(&_ValidatorMessages.CallOpts, conversionData) +} + +// PackConversionData is a free data retrieval call binding the contract method 0x51f48008. +// +// Solidity: function packConversionData((bytes32,bytes32,address,(bytes,bytes,uint64)[]) conversionData) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackConversionData(conversionData ConversionData) ([]byte, error) { + return _ValidatorMessages.Contract.PackConversionData(&_ValidatorMessages.CallOpts, conversionData) +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackL1ValidatorRegistrationMessage(opts *bind.CallOpts, validationID [32]byte, registered bool) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packL1ValidatorRegistrationMessage", validationID, registered) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackL1ValidatorRegistrationMessage(validationID [32]byte, registered bool) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, validationID, registered) +} + +// PackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0xa699c135. +// +// Solidity: function packL1ValidatorRegistrationMessage(bytes32 validationID, bool registered) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackL1ValidatorRegistrationMessage(validationID [32]byte, registered bool) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, validationID, registered) +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackL1ValidatorWeightMessage(opts *bind.CallOpts, validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packL1ValidatorWeightMessage", validationID, nonce, weight) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackL1ValidatorWeightMessage(validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, validationID, nonce, weight) +} + +// PackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x854a893f. +// +// Solidity: function packL1ValidatorWeightMessage(bytes32 validationID, uint64 nonce, uint64 weight) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackL1ValidatorWeightMessage(validationID [32]byte, nonce uint64, weight uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, validationID, nonce, weight) +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackRegisterL1ValidatorMessage(opts *bind.CallOpts, validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packRegisterL1ValidatorMessage", validationPeriod) + + if err != nil { + return *new([32]byte), *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte) + + return out0, out1, err + +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackRegisterL1ValidatorMessage(validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + return _ValidatorMessages.Contract.PackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, validationPeriod) +} + +// PackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0xe0d5478f. +// +// Solidity: function packRegisterL1ValidatorMessage((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64) validationPeriod) pure returns(bytes32, bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackRegisterL1ValidatorMessage(validationPeriod ValidatorMessagesValidationPeriod) ([32]byte, []byte, error) { + return _ValidatorMessages.Contract.PackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, validationPeriod) +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackSubnetToL1ConversionMessage(opts *bind.CallOpts, conversionID [32]byte) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packSubnetToL1ConversionMessage", conversionID) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackSubnetToL1ConversionMessage(conversionID [32]byte) ([]byte, error) { + return _ValidatorMessages.Contract.PackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, conversionID) +} + +// PackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x7f7c427a. +// +// Solidity: function packSubnetToL1ConversionMessage(bytes32 conversionID) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackSubnetToL1ConversionMessage(conversionID [32]byte) ([]byte, error) { + return _ValidatorMessages.Contract.PackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, conversionID) +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCaller) PackValidationUptimeMessage(opts *bind.CallOpts, validationID [32]byte, uptime uint64) ([]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "packValidationUptimeMessage", validationID, uptime) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesSession) PackValidationUptimeMessage(validationID [32]byte, uptime uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackValidationUptimeMessage(&_ValidatorMessages.CallOpts, validationID, uptime) +} + +// PackValidationUptimeMessage is a free data retrieval call binding the contract method 0xe1d68f30. +// +// Solidity: function packValidationUptimeMessage(bytes32 validationID, uint64 uptime) pure returns(bytes) +func (_ValidatorMessages *ValidatorMessagesCallerSession) PackValidationUptimeMessage(validationID [32]byte, uptime uint64) ([]byte, error) { + return _ValidatorMessages.Contract.PackValidationUptimeMessage(&_ValidatorMessages.CallOpts, validationID, uptime) +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackL1ValidatorRegistrationMessage(opts *bind.CallOpts, input []byte) ([32]byte, bool, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackL1ValidatorRegistrationMessage", input) + + if err != nil { + return *new([32]byte), *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(bool)).(*bool) + + return out0, out1, err + +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackL1ValidatorRegistrationMessage(input []byte) ([32]byte, bool, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorRegistrationMessage is a free data retrieval call binding the contract method 0x021de88f. +// +// Solidity: function unpackL1ValidatorRegistrationMessage(bytes input) pure returns(bytes32, bool) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackL1ValidatorRegistrationMessage(input []byte) ([32]byte, bool, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorRegistrationMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackL1ValidatorWeightMessage(opts *bind.CallOpts, input []byte) ([32]byte, uint64, uint64, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackL1ValidatorWeightMessage", input) + + if err != nil { + return *new([32]byte), *new(uint64), *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(uint64)).(*uint64) + out2 := *abi.ConvertType(out[2], new(uint64)).(*uint64) + + return out0, out1, out2, err + +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackL1ValidatorWeightMessage(input []byte) ([32]byte, uint64, uint64, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackL1ValidatorWeightMessage is a free data retrieval call binding the contract method 0x50782b0f. +// +// Solidity: function unpackL1ValidatorWeightMessage(bytes input) pure returns(bytes32, uint64, uint64) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackL1ValidatorWeightMessage(input []byte) ([32]byte, uint64, uint64, error) { + return _ValidatorMessages.Contract.UnpackL1ValidatorWeightMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackRegisterL1ValidatorMessage(opts *bind.CallOpts, input []byte) (ValidatorMessagesValidationPeriod, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackRegisterL1ValidatorMessage", input) + + if err != nil { + return *new(ValidatorMessagesValidationPeriod), err + } + + out0 := *abi.ConvertType(out[0], new(ValidatorMessagesValidationPeriod)).(*ValidatorMessagesValidationPeriod) + + return out0, err + +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackRegisterL1ValidatorMessage(input []byte) (ValidatorMessagesValidationPeriod, error) { + return _ValidatorMessages.Contract.UnpackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackRegisterL1ValidatorMessage is a free data retrieval call binding the contract method 0x9b835465. +// +// Solidity: function unpackRegisterL1ValidatorMessage(bytes input) pure returns((bytes32,bytes,bytes,uint64,(uint32,address[]),(uint32,address[]),uint64)) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackRegisterL1ValidatorMessage(input []byte) (ValidatorMessagesValidationPeriod, error) { + return _ValidatorMessages.Contract.UnpackRegisterL1ValidatorMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackSubnetToL1ConversionMessage(opts *bind.CallOpts, input []byte) ([32]byte, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackSubnetToL1ConversionMessage", input) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackSubnetToL1ConversionMessage(input []byte) ([32]byte, error) { + return _ValidatorMessages.Contract.UnpackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackSubnetToL1ConversionMessage is a free data retrieval call binding the contract method 0x4d847884. +// +// Solidity: function unpackSubnetToL1ConversionMessage(bytes input) pure returns(bytes32) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackSubnetToL1ConversionMessage(input []byte) ([32]byte, error) { + return _ValidatorMessages.Contract.UnpackSubnetToL1ConversionMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesCaller) UnpackValidationUptimeMessage(opts *bind.CallOpts, input []byte) ([32]byte, uint64, error) { + var out []interface{} + err := _ValidatorMessages.contract.Call(opts, &out, "unpackValidationUptimeMessage", input) + + if err != nil { + return *new([32]byte), *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + out1 := *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return out0, out1, err + +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesSession) UnpackValidationUptimeMessage(input []byte) ([32]byte, uint64, error) { + return _ValidatorMessages.Contract.UnpackValidationUptimeMessage(&_ValidatorMessages.CallOpts, input) +} + +// UnpackValidationUptimeMessage is a free data retrieval call binding the contract method 0x088c2463. +// +// Solidity: function unpackValidationUptimeMessage(bytes input) pure returns(bytes32, uint64) +func (_ValidatorMessages *ValidatorMessagesCallerSession) UnpackValidationUptimeMessage(input []byte) ([32]byte, uint64, error) { + return _ValidatorMessages.Contract.UnpackValidationUptimeMessage(&_ValidatorMessages.CallOpts, input) +} diff --git a/abi-bindings/go/validator-manager/interfaces/IStakingManager/IStakingManager.go b/abi-bindings/go/validator-manager/interfaces/IStakingManager/IStakingManager.go new file mode 100644 index 000000000..1fbbce3d3 --- /dev/null +++ b/abi-bindings/go/validator-manager/interfaces/IStakingManager/IStakingManager.go @@ -0,0 +1,2016 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package istakingmanager + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IStakingManagerMetaData contains all meta data concerning the IStakingManager contract. +var IStakingManagerMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startTime\",\"type\":\"uint256\"}],\"name\":\"CompletedDelegatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewards\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"}],\"name\":\"CompletedDelegatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DelegatorRewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"}],\"name\":\"DelegatorRewardRecipientChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegatorAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"validatorWeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"delegatorWeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"setWeightMessageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InitiatedDelegatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"InitiatedDelegatorRemoval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"delegationFeeBips\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"minStakeDuration\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRecipient\",\"type\":\"address\"}],\"name\":\"InitiatedStakingValidatorRegistration\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"uptime\",\"type\":\"uint64\"}],\"name\":\"UptimeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ValidatorRewardClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"}],\"name\":\"ValidatorRewardRecipientChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"changeDelegatorRewardRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"changeValidatorRewardRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"}],\"name\":\"claimDelegationFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeDelegatorRegistration\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRegistration\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"completeValidatorRemoval\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"forceInitiateDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"forceInitiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initiateDelegatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"includeUptimeProof\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"initiateValidatorRemoval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"delegationID\",\"type\":\"bytes32\"}],\"name\":\"resendUpdateDelegator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"validationID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"}],\"name\":\"submitUptimeProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// IStakingManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use IStakingManagerMetaData.ABI instead. +var IStakingManagerABI = IStakingManagerMetaData.ABI + +// IStakingManager is an auto generated Go binding around an Ethereum contract. +type IStakingManager struct { + IStakingManagerCaller // Read-only binding to the contract + IStakingManagerTransactor // Write-only binding to the contract + IStakingManagerFilterer // Log filterer for contract events +} + +// IStakingManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type IStakingManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IStakingManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IStakingManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IStakingManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IStakingManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IStakingManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IStakingManagerSession struct { + Contract *IStakingManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IStakingManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IStakingManagerCallerSession struct { + Contract *IStakingManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IStakingManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IStakingManagerTransactorSession struct { + Contract *IStakingManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IStakingManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type IStakingManagerRaw struct { + Contract *IStakingManager // Generic contract binding to access the raw methods on +} + +// IStakingManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IStakingManagerCallerRaw struct { + Contract *IStakingManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// IStakingManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IStakingManagerTransactorRaw struct { + Contract *IStakingManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewIStakingManager creates a new instance of IStakingManager, bound to a specific deployed contract. +func NewIStakingManager(address common.Address, backend bind.ContractBackend) (*IStakingManager, error) { + contract, err := bindIStakingManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IStakingManager{IStakingManagerCaller: IStakingManagerCaller{contract: contract}, IStakingManagerTransactor: IStakingManagerTransactor{contract: contract}, IStakingManagerFilterer: IStakingManagerFilterer{contract: contract}}, nil +} + +// NewIStakingManagerCaller creates a new read-only instance of IStakingManager, bound to a specific deployed contract. +func NewIStakingManagerCaller(address common.Address, caller bind.ContractCaller) (*IStakingManagerCaller, error) { + contract, err := bindIStakingManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IStakingManagerCaller{contract: contract}, nil +} + +// NewIStakingManagerTransactor creates a new write-only instance of IStakingManager, bound to a specific deployed contract. +func NewIStakingManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*IStakingManagerTransactor, error) { + contract, err := bindIStakingManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IStakingManagerTransactor{contract: contract}, nil +} + +// NewIStakingManagerFilterer creates a new log filterer instance of IStakingManager, bound to a specific deployed contract. +func NewIStakingManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*IStakingManagerFilterer, error) { + contract, err := bindIStakingManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IStakingManagerFilterer{contract: contract}, nil +} + +// bindIStakingManager binds a generic wrapper to an already deployed contract. +func bindIStakingManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IStakingManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IStakingManager *IStakingManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IStakingManager.Contract.IStakingManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IStakingManager *IStakingManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IStakingManager.Contract.IStakingManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IStakingManager *IStakingManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IStakingManager.Contract.IStakingManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IStakingManager *IStakingManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IStakingManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IStakingManager *IStakingManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IStakingManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IStakingManager *IStakingManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IStakingManager.Contract.contract.Transact(opts, method, params...) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address recipient) returns() +func (_IStakingManager *IStakingManagerTransactor) ChangeDelegatorRewardRecipient(opts *bind.TransactOpts, delegationID [32]byte, recipient common.Address) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "changeDelegatorRewardRecipient", delegationID, recipient) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address recipient) returns() +func (_IStakingManager *IStakingManagerSession) ChangeDelegatorRewardRecipient(delegationID [32]byte, recipient common.Address) (*types.Transaction, error) { + return _IStakingManager.Contract.ChangeDelegatorRewardRecipient(&_IStakingManager.TransactOpts, delegationID, recipient) +} + +// ChangeDelegatorRewardRecipient is a paid mutator transaction binding the contract method 0xfb8b11dd. +// +// Solidity: function changeDelegatorRewardRecipient(bytes32 delegationID, address recipient) returns() +func (_IStakingManager *IStakingManagerTransactorSession) ChangeDelegatorRewardRecipient(delegationID [32]byte, recipient common.Address) (*types.Transaction, error) { + return _IStakingManager.Contract.ChangeDelegatorRewardRecipient(&_IStakingManager.TransactOpts, delegationID, recipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address recipient) returns() +func (_IStakingManager *IStakingManagerTransactor) ChangeValidatorRewardRecipient(opts *bind.TransactOpts, validationID [32]byte, recipient common.Address) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "changeValidatorRewardRecipient", validationID, recipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address recipient) returns() +func (_IStakingManager *IStakingManagerSession) ChangeValidatorRewardRecipient(validationID [32]byte, recipient common.Address) (*types.Transaction, error) { + return _IStakingManager.Contract.ChangeValidatorRewardRecipient(&_IStakingManager.TransactOpts, validationID, recipient) +} + +// ChangeValidatorRewardRecipient is a paid mutator transaction binding the contract method 0x8ef34c98. +// +// Solidity: function changeValidatorRewardRecipient(bytes32 validationID, address recipient) returns() +func (_IStakingManager *IStakingManagerTransactorSession) ChangeValidatorRewardRecipient(validationID [32]byte, recipient common.Address) (*types.Transaction, error) { + return _IStakingManager.Contract.ChangeValidatorRewardRecipient(&_IStakingManager.TransactOpts, validationID, recipient) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_IStakingManager *IStakingManagerTransactor) ClaimDelegationFees(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "claimDelegationFees", validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_IStakingManager *IStakingManagerSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _IStakingManager.Contract.ClaimDelegationFees(&_IStakingManager.TransactOpts, validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_IStakingManager *IStakingManagerTransactorSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _IStakingManager.Contract.ClaimDelegationFees(&_IStakingManager.TransactOpts, validationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactor) CompleteDelegatorRegistration(opts *bind.TransactOpts, delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "completeDelegatorRegistration", delegationID, messageIndex) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerSession) CompleteDelegatorRegistration(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteDelegatorRegistration(&_IStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x60ad7784. +// +// Solidity: function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactorSession) CompleteDelegatorRegistration(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteDelegatorRegistration(&_IStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactor) CompleteDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "completeDelegatorRemoval", delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerSession) CompleteDelegatorRemoval(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteDelegatorRemoval(&_IStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteDelegatorRemoval is a paid mutator transaction binding the contract method 0x13409645. +// +// Solidity: function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactorSession) CompleteDelegatorRemoval(delegationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteDelegatorRemoval(&_IStakingManager.TransactOpts, delegationID, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_IStakingManager *IStakingManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_IStakingManager *IStakingManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteValidatorRegistration(&_IStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns(bytes32) +func (_IStakingManager *IStakingManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteValidatorRegistration(&_IStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_IStakingManager *IStakingManagerTransactor) CompleteValidatorRemoval(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "completeValidatorRemoval", messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_IStakingManager *IStakingManagerSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteValidatorRemoval(&_IStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRemoval is a paid mutator transaction binding the contract method 0x9681d940. +// +// Solidity: function completeValidatorRemoval(uint32 messageIndex) returns(bytes32) +func (_IStakingManager *IStakingManagerTransactorSession) CompleteValidatorRemoval(messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.CompleteValidatorRemoval(&_IStakingManager.TransactOpts, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactor) ForceInitiateDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "forceInitiateDelegatorRemoval", delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerSession) ForceInitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.ForceInitiateDelegatorRemoval(&_IStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x27bf60cd. +// +// Solidity: function forceInitiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactorSession) ForceInitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.ForceInitiateDelegatorRemoval(&_IStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactor) ForceInitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "forceInitiateValidatorRemoval", validationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerSession) ForceInitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.ForceInitiateValidatorRemoval(&_IStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// ForceInitiateValidatorRemoval is a paid mutator transaction binding the contract method 0x16679564. +// +// Solidity: function forceInitiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactorSession) ForceInitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.ForceInitiateValidatorRemoval(&_IStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactor) InitiateDelegatorRemoval(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "initiateDelegatorRemoval", delegationID, includeUptimeProof, messageIndex) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerSession) InitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.InitiateDelegatorRemoval(&_IStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitiateDelegatorRemoval is a paid mutator transaction binding the contract method 0x2aa56638. +// +// Solidity: function initiateDelegatorRemoval(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactorSession) InitiateDelegatorRemoval(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.InitiateDelegatorRemoval(&_IStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactor) InitiateValidatorRemoval(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "initiateValidatorRemoval", validationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerSession) InitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.InitiateValidatorRemoval(&_IStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitiateValidatorRemoval is a paid mutator transaction binding the contract method 0xb2c1712e. +// +// Solidity: function initiateValidatorRemoval(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactorSession) InitiateValidatorRemoval(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.InitiateValidatorRemoval(&_IStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_IStakingManager *IStakingManagerTransactor) ResendUpdateDelegator(opts *bind.TransactOpts, delegationID [32]byte) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "resendUpdateDelegator", delegationID) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_IStakingManager *IStakingManagerSession) ResendUpdateDelegator(delegationID [32]byte) (*types.Transaction, error) { + return _IStakingManager.Contract.ResendUpdateDelegator(&_IStakingManager.TransactOpts, delegationID) +} + +// ResendUpdateDelegator is a paid mutator transaction binding the contract method 0x245dafcb. +// +// Solidity: function resendUpdateDelegator(bytes32 delegationID) returns() +func (_IStakingManager *IStakingManagerTransactorSession) ResendUpdateDelegator(delegationID [32]byte) (*types.Transaction, error) { + return _IStakingManager.Contract.ResendUpdateDelegator(&_IStakingManager.TransactOpts, delegationID) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactor) SubmitUptimeProof(opts *bind.TransactOpts, validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.contract.Transact(opts, "submitUptimeProof", validationID, messageIndex) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerSession) SubmitUptimeProof(validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.SubmitUptimeProof(&_IStakingManager.TransactOpts, validationID, messageIndex) +} + +// SubmitUptimeProof is a paid mutator transaction binding the contract method 0x25e1c776. +// +// Solidity: function submitUptimeProof(bytes32 validationID, uint32 messageIndex) returns() +func (_IStakingManager *IStakingManagerTransactorSession) SubmitUptimeProof(validationID [32]byte, messageIndex uint32) (*types.Transaction, error) { + return _IStakingManager.Contract.SubmitUptimeProof(&_IStakingManager.TransactOpts, validationID, messageIndex) +} + +// IStakingManagerCompletedDelegatorRegistrationIterator is returned from FilterCompletedDelegatorRegistration and is used to iterate over the raw logs and unpacked data for CompletedDelegatorRegistration events raised by the IStakingManager contract. +type IStakingManagerCompletedDelegatorRegistrationIterator struct { + Event *IStakingManagerCompletedDelegatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerCompletedDelegatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerCompletedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerCompletedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerCompletedDelegatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerCompletedDelegatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerCompletedDelegatorRegistration represents a CompletedDelegatorRegistration event raised by the IStakingManager contract. +type IStakingManagerCompletedDelegatorRegistration struct { + DelegationID [32]byte + ValidationID [32]byte + StartTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedDelegatorRegistration is a free log retrieval operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_IStakingManager *IStakingManagerFilterer) FilterCompletedDelegatorRegistration(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*IStakingManagerCompletedDelegatorRegistrationIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "CompletedDelegatorRegistration", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &IStakingManagerCompletedDelegatorRegistrationIterator{contract: _IStakingManager.contract, event: "CompletedDelegatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchCompletedDelegatorRegistration is a free log subscription operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_IStakingManager *IStakingManagerFilterer) WatchCompletedDelegatorRegistration(opts *bind.WatchOpts, sink chan<- *IStakingManagerCompletedDelegatorRegistration, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "CompletedDelegatorRegistration", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerCompletedDelegatorRegistration) + if err := _IStakingManager.contract.UnpackLog(event, "CompletedDelegatorRegistration", 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 +} + +// ParseCompletedDelegatorRegistration is a log parse operation binding the contract event 0x3886b7389bccb22cac62838dee3f400cf8b22289295283e01a2c7093f93dd5aa. +// +// Solidity: event CompletedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime) +func (_IStakingManager *IStakingManagerFilterer) ParseCompletedDelegatorRegistration(log types.Log) (*IStakingManagerCompletedDelegatorRegistration, error) { + event := new(IStakingManagerCompletedDelegatorRegistration) + if err := _IStakingManager.contract.UnpackLog(event, "CompletedDelegatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerCompletedDelegatorRemovalIterator is returned from FilterCompletedDelegatorRemoval and is used to iterate over the raw logs and unpacked data for CompletedDelegatorRemoval events raised by the IStakingManager contract. +type IStakingManagerCompletedDelegatorRemovalIterator struct { + Event *IStakingManagerCompletedDelegatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerCompletedDelegatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerCompletedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerCompletedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerCompletedDelegatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerCompletedDelegatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerCompletedDelegatorRemoval represents a CompletedDelegatorRemoval event raised by the IStakingManager contract. +type IStakingManagerCompletedDelegatorRemoval struct { + DelegationID [32]byte + ValidationID [32]byte + Rewards *big.Int + Fees *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCompletedDelegatorRemoval is a free log retrieval operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_IStakingManager *IStakingManagerFilterer) FilterCompletedDelegatorRemoval(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*IStakingManagerCompletedDelegatorRemovalIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "CompletedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &IStakingManagerCompletedDelegatorRemovalIterator{contract: _IStakingManager.contract, event: "CompletedDelegatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchCompletedDelegatorRemoval is a free log subscription operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_IStakingManager *IStakingManagerFilterer) WatchCompletedDelegatorRemoval(opts *bind.WatchOpts, sink chan<- *IStakingManagerCompletedDelegatorRemoval, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "CompletedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerCompletedDelegatorRemoval) + if err := _IStakingManager.contract.UnpackLog(event, "CompletedDelegatorRemoval", 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 +} + +// ParseCompletedDelegatorRemoval is a log parse operation binding the contract event 0x5ecc5b26a9265302cf871229b3d983e5ca57dbb1448966c6c58b2d3c68bc7f7e. +// +// Solidity: event CompletedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_IStakingManager *IStakingManagerFilterer) ParseCompletedDelegatorRemoval(log types.Log) (*IStakingManagerCompletedDelegatorRemoval, error) { + event := new(IStakingManagerCompletedDelegatorRemoval) + if err := _IStakingManager.contract.UnpackLog(event, "CompletedDelegatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerDelegatorRewardClaimedIterator is returned from FilterDelegatorRewardClaimed and is used to iterate over the raw logs and unpacked data for DelegatorRewardClaimed events raised by the IStakingManager contract. +type IStakingManagerDelegatorRewardClaimedIterator struct { + Event *IStakingManagerDelegatorRewardClaimed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerDelegatorRewardClaimedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerDelegatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerDelegatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerDelegatorRewardClaimedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerDelegatorRewardClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerDelegatorRewardClaimed represents a DelegatorRewardClaimed event raised by the IStakingManager contract. +type IStakingManagerDelegatorRewardClaimed struct { + DelegationID [32]byte + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRewardClaimed is a free log retrieval operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_IStakingManager *IStakingManagerFilterer) FilterDelegatorRewardClaimed(opts *bind.FilterOpts, delegationID [][32]byte, recipient []common.Address) (*IStakingManagerDelegatorRewardClaimedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "DelegatorRewardClaimed", delegationIDRule, recipientRule) + if err != nil { + return nil, err + } + return &IStakingManagerDelegatorRewardClaimedIterator{contract: _IStakingManager.contract, event: "DelegatorRewardClaimed", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRewardClaimed is a free log subscription operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_IStakingManager *IStakingManagerFilterer) WatchDelegatorRewardClaimed(opts *bind.WatchOpts, sink chan<- *IStakingManagerDelegatorRewardClaimed, delegationID [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "DelegatorRewardClaimed", delegationIDRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerDelegatorRewardClaimed) + if err := _IStakingManager.contract.UnpackLog(event, "DelegatorRewardClaimed", 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 +} + +// ParseDelegatorRewardClaimed is a log parse operation binding the contract event 0x3ffc31181aadb250503101bd718e5fce8c27650af8d3525b9f60996756efaf63. +// +// Solidity: event DelegatorRewardClaimed(bytes32 indexed delegationID, address indexed recipient, uint256 amount) +func (_IStakingManager *IStakingManagerFilterer) ParseDelegatorRewardClaimed(log types.Log) (*IStakingManagerDelegatorRewardClaimed, error) { + event := new(IStakingManagerDelegatorRewardClaimed) + if err := _IStakingManager.contract.UnpackLog(event, "DelegatorRewardClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerDelegatorRewardRecipientChangedIterator is returned from FilterDelegatorRewardRecipientChanged and is used to iterate over the raw logs and unpacked data for DelegatorRewardRecipientChanged events raised by the IStakingManager contract. +type IStakingManagerDelegatorRewardRecipientChangedIterator struct { + Event *IStakingManagerDelegatorRewardRecipientChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerDelegatorRewardRecipientChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerDelegatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerDelegatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerDelegatorRewardRecipientChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerDelegatorRewardRecipientChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerDelegatorRewardRecipientChanged represents a DelegatorRewardRecipientChanged event raised by the IStakingManager contract. +type IStakingManagerDelegatorRewardRecipientChanged struct { + DelegationID [32]byte + Recipient common.Address + OldRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRewardRecipientChanged is a free log retrieval operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_IStakingManager *IStakingManagerFilterer) FilterDelegatorRewardRecipientChanged(opts *bind.FilterOpts, delegationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (*IStakingManagerDelegatorRewardRecipientChangedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "DelegatorRewardRecipientChanged", delegationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return &IStakingManagerDelegatorRewardRecipientChangedIterator{contract: _IStakingManager.contract, event: "DelegatorRewardRecipientChanged", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRewardRecipientChanged is a free log subscription operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_IStakingManager *IStakingManagerFilterer) WatchDelegatorRewardRecipientChanged(opts *bind.WatchOpts, sink chan<- *IStakingManagerDelegatorRewardRecipientChanged, delegationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "DelegatorRewardRecipientChanged", delegationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerDelegatorRewardRecipientChanged) + if err := _IStakingManager.contract.UnpackLog(event, "DelegatorRewardRecipientChanged", 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 +} + +// ParseDelegatorRewardRecipientChanged is a log parse operation binding the contract event 0x6b30f219ab3cc1c43b394679707f3856ff2f3c6f1f6c97f383c6b16687a1e005. +// +// Solidity: event DelegatorRewardRecipientChanged(bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient) +func (_IStakingManager *IStakingManagerFilterer) ParseDelegatorRewardRecipientChanged(log types.Log) (*IStakingManagerDelegatorRewardRecipientChanged, error) { + event := new(IStakingManagerDelegatorRewardRecipientChanged) + if err := _IStakingManager.contract.UnpackLog(event, "DelegatorRewardRecipientChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerInitiatedDelegatorRegistrationIterator is returned from FilterInitiatedDelegatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedDelegatorRegistration events raised by the IStakingManager contract. +type IStakingManagerInitiatedDelegatorRegistrationIterator struct { + Event *IStakingManagerInitiatedDelegatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerInitiatedDelegatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerInitiatedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerInitiatedDelegatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerInitiatedDelegatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerInitiatedDelegatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerInitiatedDelegatorRegistration represents a InitiatedDelegatorRegistration event raised by the IStakingManager contract. +type IStakingManagerInitiatedDelegatorRegistration struct { + DelegationID [32]byte + ValidationID [32]byte + DelegatorAddress common.Address + Nonce uint64 + ValidatorWeight uint64 + DelegatorWeight uint64 + SetWeightMessageID [32]byte + RewardRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedDelegatorRegistration is a free log retrieval operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_IStakingManager *IStakingManagerFilterer) FilterInitiatedDelegatorRegistration(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (*IStakingManagerInitiatedDelegatorRegistrationIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "InitiatedDelegatorRegistration", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return &IStakingManagerInitiatedDelegatorRegistrationIterator{contract: _IStakingManager.contract, event: "InitiatedDelegatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedDelegatorRegistration is a free log subscription operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_IStakingManager *IStakingManagerFilterer) WatchInitiatedDelegatorRegistration(opts *bind.WatchOpts, sink chan<- *IStakingManagerInitiatedDelegatorRegistration, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "InitiatedDelegatorRegistration", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerInitiatedDelegatorRegistration) + if err := _IStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRegistration", 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 +} + +// ParseInitiatedDelegatorRegistration is a log parse operation binding the contract event 0x77499a5603260ef2b34698d88b31f7b1acf28c7b134ad4e3fa636501e6064d77. +// +// Solidity: event InitiatedDelegatorRegistration(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID, address rewardRecipient) +func (_IStakingManager *IStakingManagerFilterer) ParseInitiatedDelegatorRegistration(log types.Log) (*IStakingManagerInitiatedDelegatorRegistration, error) { + event := new(IStakingManagerInitiatedDelegatorRegistration) + if err := _IStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerInitiatedDelegatorRemovalIterator is returned from FilterInitiatedDelegatorRemoval and is used to iterate over the raw logs and unpacked data for InitiatedDelegatorRemoval events raised by the IStakingManager contract. +type IStakingManagerInitiatedDelegatorRemovalIterator struct { + Event *IStakingManagerInitiatedDelegatorRemoval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerInitiatedDelegatorRemovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerInitiatedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerInitiatedDelegatorRemoval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerInitiatedDelegatorRemovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerInitiatedDelegatorRemovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerInitiatedDelegatorRemoval represents a InitiatedDelegatorRemoval event raised by the IStakingManager contract. +type IStakingManagerInitiatedDelegatorRemoval struct { + DelegationID [32]byte + ValidationID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedDelegatorRemoval is a free log retrieval operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_IStakingManager *IStakingManagerFilterer) FilterInitiatedDelegatorRemoval(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*IStakingManagerInitiatedDelegatorRemovalIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "InitiatedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &IStakingManagerInitiatedDelegatorRemovalIterator{contract: _IStakingManager.contract, event: "InitiatedDelegatorRemoval", logs: logs, sub: sub}, nil +} + +// WatchInitiatedDelegatorRemoval is a free log subscription operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_IStakingManager *IStakingManagerFilterer) WatchInitiatedDelegatorRemoval(opts *bind.WatchOpts, sink chan<- *IStakingManagerInitiatedDelegatorRemoval, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "InitiatedDelegatorRemoval", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerInitiatedDelegatorRemoval) + if err := _IStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRemoval", 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 +} + +// ParseInitiatedDelegatorRemoval is a log parse operation binding the contract event 0x5abe543af12bb7f76f6fa9daaa9d95d181c5e90566df58d3c012216b6245eeaf. +// +// Solidity: event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID) +func (_IStakingManager *IStakingManagerFilterer) ParseInitiatedDelegatorRemoval(log types.Log) (*IStakingManagerInitiatedDelegatorRemoval, error) { + event := new(IStakingManagerInitiatedDelegatorRemoval) + if err := _IStakingManager.contract.UnpackLog(event, "InitiatedDelegatorRemoval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerInitiatedStakingValidatorRegistrationIterator is returned from FilterInitiatedStakingValidatorRegistration and is used to iterate over the raw logs and unpacked data for InitiatedStakingValidatorRegistration events raised by the IStakingManager contract. +type IStakingManagerInitiatedStakingValidatorRegistrationIterator struct { + Event *IStakingManagerInitiatedStakingValidatorRegistration // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerInitiatedStakingValidatorRegistrationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerInitiatedStakingValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerInitiatedStakingValidatorRegistration) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerInitiatedStakingValidatorRegistrationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerInitiatedStakingValidatorRegistrationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerInitiatedStakingValidatorRegistration represents a InitiatedStakingValidatorRegistration event raised by the IStakingManager contract. +type IStakingManagerInitiatedStakingValidatorRegistration struct { + ValidationID [32]byte + Owner common.Address + DelegationFeeBips uint16 + MinStakeDuration uint64 + RewardRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitiatedStakingValidatorRegistration is a free log retrieval operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_IStakingManager *IStakingManagerFilterer) FilterInitiatedStakingValidatorRegistration(opts *bind.FilterOpts, validationID [][32]byte, owner []common.Address) (*IStakingManagerInitiatedStakingValidatorRegistrationIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "InitiatedStakingValidatorRegistration", validationIDRule, ownerRule) + if err != nil { + return nil, err + } + return &IStakingManagerInitiatedStakingValidatorRegistrationIterator{contract: _IStakingManager.contract, event: "InitiatedStakingValidatorRegistration", logs: logs, sub: sub}, nil +} + +// WatchInitiatedStakingValidatorRegistration is a free log subscription operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_IStakingManager *IStakingManagerFilterer) WatchInitiatedStakingValidatorRegistration(opts *bind.WatchOpts, sink chan<- *IStakingManagerInitiatedStakingValidatorRegistration, validationID [][32]byte, owner []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "InitiatedStakingValidatorRegistration", validationIDRule, ownerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerInitiatedStakingValidatorRegistration) + if err := _IStakingManager.contract.UnpackLog(event, "InitiatedStakingValidatorRegistration", 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 +} + +// ParseInitiatedStakingValidatorRegistration is a log parse operation binding the contract event 0xf51ab9b5253693af2f675b23c4042ccac671873d5f188e405b30019f4c159b7f. +// +// Solidity: event InitiatedStakingValidatorRegistration(bytes32 indexed validationID, address indexed owner, uint16 delegationFeeBips, uint64 minStakeDuration, address rewardRecipient) +func (_IStakingManager *IStakingManagerFilterer) ParseInitiatedStakingValidatorRegistration(log types.Log) (*IStakingManagerInitiatedStakingValidatorRegistration, error) { + event := new(IStakingManagerInitiatedStakingValidatorRegistration) + if err := _IStakingManager.contract.UnpackLog(event, "InitiatedStakingValidatorRegistration", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerUptimeUpdatedIterator is returned from FilterUptimeUpdated and is used to iterate over the raw logs and unpacked data for UptimeUpdated events raised by the IStakingManager contract. +type IStakingManagerUptimeUpdatedIterator struct { + Event *IStakingManagerUptimeUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerUptimeUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerUptimeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerUptimeUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerUptimeUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerUptimeUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerUptimeUpdated represents a UptimeUpdated event raised by the IStakingManager contract. +type IStakingManagerUptimeUpdated struct { + ValidationID [32]byte + Uptime uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUptimeUpdated is a free log retrieval operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_IStakingManager *IStakingManagerFilterer) FilterUptimeUpdated(opts *bind.FilterOpts, validationID [][32]byte) (*IStakingManagerUptimeUpdatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "UptimeUpdated", validationIDRule) + if err != nil { + return nil, err + } + return &IStakingManagerUptimeUpdatedIterator{contract: _IStakingManager.contract, event: "UptimeUpdated", logs: logs, sub: sub}, nil +} + +// WatchUptimeUpdated is a free log subscription operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_IStakingManager *IStakingManagerFilterer) WatchUptimeUpdated(opts *bind.WatchOpts, sink chan<- *IStakingManagerUptimeUpdated, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "UptimeUpdated", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerUptimeUpdated) + if err := _IStakingManager.contract.UnpackLog(event, "UptimeUpdated", 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 +} + +// ParseUptimeUpdated is a log parse operation binding the contract event 0xec44148e8ff271f2d0bacef1142154abacb0abb3a29eb3eb50e2ca97e86d0435. +// +// Solidity: event UptimeUpdated(bytes32 indexed validationID, uint64 uptime) +func (_IStakingManager *IStakingManagerFilterer) ParseUptimeUpdated(log types.Log) (*IStakingManagerUptimeUpdated, error) { + event := new(IStakingManagerUptimeUpdated) + if err := _IStakingManager.contract.UnpackLog(event, "UptimeUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerValidatorRewardClaimedIterator is returned from FilterValidatorRewardClaimed and is used to iterate over the raw logs and unpacked data for ValidatorRewardClaimed events raised by the IStakingManager contract. +type IStakingManagerValidatorRewardClaimedIterator struct { + Event *IStakingManagerValidatorRewardClaimed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerValidatorRewardClaimedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerValidatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerValidatorRewardClaimed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerValidatorRewardClaimedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerValidatorRewardClaimedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerValidatorRewardClaimed represents a ValidatorRewardClaimed event raised by the IStakingManager contract. +type IStakingManagerValidatorRewardClaimed struct { + ValidationID [32]byte + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRewardClaimed is a free log retrieval operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_IStakingManager *IStakingManagerFilterer) FilterValidatorRewardClaimed(opts *bind.FilterOpts, validationID [][32]byte, recipient []common.Address) (*IStakingManagerValidatorRewardClaimedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "ValidatorRewardClaimed", validationIDRule, recipientRule) + if err != nil { + return nil, err + } + return &IStakingManagerValidatorRewardClaimedIterator{contract: _IStakingManager.contract, event: "ValidatorRewardClaimed", logs: logs, sub: sub}, nil +} + +// WatchValidatorRewardClaimed is a free log subscription operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_IStakingManager *IStakingManagerFilterer) WatchValidatorRewardClaimed(opts *bind.WatchOpts, sink chan<- *IStakingManagerValidatorRewardClaimed, validationID [][32]byte, recipient []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "ValidatorRewardClaimed", validationIDRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerValidatorRewardClaimed) + if err := _IStakingManager.contract.UnpackLog(event, "ValidatorRewardClaimed", 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 +} + +// ParseValidatorRewardClaimed is a log parse operation binding the contract event 0x875feb58aa30eeee040d55b00249c5c8c5af4f27c95cd29d64180ad67400c6e4. +// +// Solidity: event ValidatorRewardClaimed(bytes32 indexed validationID, address indexed recipient, uint256 amount) +func (_IStakingManager *IStakingManagerFilterer) ParseValidatorRewardClaimed(log types.Log) (*IStakingManagerValidatorRewardClaimed, error) { + event := new(IStakingManagerValidatorRewardClaimed) + if err := _IStakingManager.contract.UnpackLog(event, "ValidatorRewardClaimed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IStakingManagerValidatorRewardRecipientChangedIterator is returned from FilterValidatorRewardRecipientChanged and is used to iterate over the raw logs and unpacked data for ValidatorRewardRecipientChanged events raised by the IStakingManager contract. +type IStakingManagerValidatorRewardRecipientChangedIterator struct { + Event *IStakingManagerValidatorRewardRecipientChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IStakingManagerValidatorRewardRecipientChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IStakingManagerValidatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IStakingManagerValidatorRewardRecipientChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IStakingManagerValidatorRewardRecipientChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IStakingManagerValidatorRewardRecipientChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IStakingManagerValidatorRewardRecipientChanged represents a ValidatorRewardRecipientChanged event raised by the IStakingManager contract. +type IStakingManagerValidatorRewardRecipientChanged struct { + ValidationID [32]byte + Recipient common.Address + OldRecipient common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRewardRecipientChanged is a free log retrieval operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_IStakingManager *IStakingManagerFilterer) FilterValidatorRewardRecipientChanged(opts *bind.FilterOpts, validationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (*IStakingManagerValidatorRewardRecipientChangedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _IStakingManager.contract.FilterLogs(opts, "ValidatorRewardRecipientChanged", validationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return &IStakingManagerValidatorRewardRecipientChangedIterator{contract: _IStakingManager.contract, event: "ValidatorRewardRecipientChanged", logs: logs, sub: sub}, nil +} + +// WatchValidatorRewardRecipientChanged is a free log subscription operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_IStakingManager *IStakingManagerFilterer) WatchValidatorRewardRecipientChanged(opts *bind.WatchOpts, sink chan<- *IStakingManagerValidatorRewardRecipientChanged, validationID [][32]byte, recipient []common.Address, oldRecipient []common.Address) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var oldRecipientRule []interface{} + for _, oldRecipientItem := range oldRecipient { + oldRecipientRule = append(oldRecipientRule, oldRecipientItem) + } + + logs, sub, err := _IStakingManager.contract.WatchLogs(opts, "ValidatorRewardRecipientChanged", validationIDRule, recipientRule, oldRecipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IStakingManagerValidatorRewardRecipientChanged) + if err := _IStakingManager.contract.UnpackLog(event, "ValidatorRewardRecipientChanged", 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 +} + +// ParseValidatorRewardRecipientChanged is a log parse operation binding the contract event 0x28c6fc4db51556a07b41aa23b91cedb22c02a7560c431a31255c03ca6ad61c33. +// +// Solidity: event ValidatorRewardRecipientChanged(bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient) +func (_IStakingManager *IStakingManagerFilterer) ParseValidatorRewardRecipientChanged(log types.Log) (*IStakingManagerValidatorRewardRecipientChanged, error) { + event := new(IStakingManagerValidatorRewardRecipientChanged) + if err := _IStakingManager.contract.UnpackLog(event, "ValidatorRewardRecipientChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/tests/contracts/foundry.toml b/foundry.toml similarity index 74% rename from tests/contracts/foundry.toml rename to foundry.toml index 5607c03a7..1bd163013 100644 --- a/tests/contracts/foundry.toml +++ b/foundry.toml @@ -1,9 +1,13 @@ [profile.default] -src = 'src' +src = 'icm-contracts/contracts' out = 'out' -libs = ['lib'] -solc_version = '0.8.18' +libs = ['icm-contracts/lib'] +solc_version = '0.8.25' +evm_version = 'shanghai' test = 'tests' +bytecode_hash = "none" +optimizer = true +optimizer_runs = 200 [fmt] line_length = 100 diff --git a/go.mod b/go.mod index 6a5223239..efa57e8ad 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ tool ( require ( github.com/alexliesenfeld/health v0.8.1 github.com/ava-labs/avalanchego v1.14.0-fuji - github.com/ava-labs/icm-contracts v1.0.10-0.20251021215726-c64f31020739 github.com/ava-labs/libevm v1.13.15-0.20251003195629-910e897c54c3 github.com/ava-labs/subnet-evm v0.8.0-fuji github.com/aws/aws-sdk-go-v2 v1.39.5 @@ -24,6 +23,8 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.23.2 github.com/redis/go-redis/v9 v9.16.0 + github.com/segmentio/encoding v0.5.3 + github.com/spf13/cobra v1.10.1 github.com/spf13/pflag v1.0.10 github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 @@ -32,6 +33,7 @@ require ( go.uber.org/mock v0.6.0 go.uber.org/zap v1.27.0 golang.org/x/sync v0.17.0 + golang.org/x/tools v0.38.0 google.golang.org/grpc v1.76.0 google.golang.org/protobuf v1.36.10 ) @@ -303,7 +305,6 @@ require ( github.com/sashamelentyev/usestdlibvars v1.28.0 // indirect github.com/securego/gosec/v2 v2.22.2 // indirect github.com/segmentio/asm v1.2.1 // indirect - github.com/segmentio/encoding v0.5.3 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect @@ -313,7 +314,6 @@ require ( github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/status-im/keycard-go v0.2.0 // indirect github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect @@ -375,7 +375,6 @@ require ( golang.org/x/term v0.36.0 // indirect golang.org/x/text v0.30.0 // indirect golang.org/x/time v0.12.0 // indirect - golang.org/x/tools v0.38.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251007200510-49b9836ed3ff // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff // indirect diff --git a/go.sum b/go.sum index 6f07a0bef..45b08cbfd 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,6 @@ github.com/ava-labs/coreth v0.15.4-rc.4 h1:ze7/IwDptWG1u2d32uUZz9Ix9ycVUtlB8Jufu github.com/ava-labs/coreth v0.15.4-rc.4/go.mod h1:yVwuMyPkZ48xzZ0y2OdIwaoUqvSsgPYoodyX9BZJ2uo= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.13 h1:obPwnVCkF5+B2f8WbTepHj0ZgiW21vKUgFCtATuAYNY= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.13/go.mod h1:gsGr1ICjokI9CyPaaRHMqDoDCaT1VguC/IyOTx6rJ14= -github.com/ava-labs/icm-contracts v1.0.10-0.20251021215726-c64f31020739 h1:OfTZbb4hZnaZ1Di1ytId5uZ74N0uPWzMRCAeYIBxVYU= -github.com/ava-labs/icm-contracts v1.0.10-0.20251021215726-c64f31020739/go.mod h1:2/t/HuTvWfsPBzSc9/w91gGGLL2LCUEV51njAsZDxmg= github.com/ava-labs/libevm v1.13.15-0.20251003195629-910e897c54c3 h1:1YeVupq12lUT9FJh7kH5InEVIeGWyAAoTBfyqYpNJaM= github.com/ava-labs/libevm v1.13.15-0.20251003195629-910e897c54c3/go.mod h1:ivRC/KojP8sai7j8WnpXIReQpcRklL2bIzoysnjpARQ= github.com/ava-labs/subnet-evm v0.8.0-fuji h1:15GuP6ZWgHjuY2rU2gGm1V3Ye+/N3fRQJ8HAE/G+aag= diff --git a/icm-contracts/CONTRIBUTING.md b/icm-contracts/CONTRIBUTING.md new file mode 100644 index 000000000..b52f318d0 --- /dev/null +++ b/icm-contracts/CONTRIBUTING.md @@ -0,0 +1,52 @@ +# How to Contribute to Teleporter + +## Setup + +To start developing on Teleporter, you'll need Solidity >= v0.8.25. [Foundry](https://book.getfoundry.sh/getting-started/installation) is the recommended development toolkit for working with Teleporter, and it comes bundled with the required Solidity version. To run the tests and linter locally, you'll need the dependencies described in [Setup](./README.md#setup), as well as [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) + +## Issues + +### Security + +- Do not open up a GitHub issue if it relates to a security vulnerability in Teleporter, and instead refer to our [security policy](./SECURITY.md). + +### Making an Issue + +- Check that the issue you're filing doesn't already exist by searching under [issues](https://github.com/ava-labs/icm-contracts/issues). +- If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/ava-labs/icm-contracts/issues/new/choose). Be sure to include a _title and clear description_ with as much relevant information as possible. + +## Features + +- If you want to start a discussion about the development of a new feature or the modfiication of an existing one, start a thread under GitHub [discussions](https://github.com/ava-labs/icm-contracts/discussions/categories/ideas). +- Post a thread about your idea and why it should be added to Teleporter. +- Don't start working on a pull request until you've received positive feedback from the maintainers. + +## Pull Request Guidelines + +- Open a new GitHub pull request containing your changes. +- All commits must be [signed](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits). +- Ensure the PR description clearly describes the problem and solution, and how the change was tested. Include the relevant issue number if applicable. +- If your PR isn't ready to be reviewed just yet, you can open it as a draft to collect early feedback on your changes. +- Once the PR is ready for review, mark it as ready-for-review and request review from one of the maintainers. + +### Testing + +See [E2E Tests](./README.md#e2e-tests) + +### Linting + +- Run the Solidity and Golang linters + +```sh +./scripts/lint.sh +``` + +### Continuous Integration (CI) + +- Pull requests will generally not be approved or merged unless they pass CI. + +## Other + +### Do you have questions about the source code? + +- Ask any question about ICM or ICM contracts under GitHub [discussions](https://github.com/ava-labs/icm-contracts/discussions/categories/q-a). diff --git a/icm-contracts/README.md b/icm-contracts/README.md new file mode 100644 index 000000000..64a119922 --- /dev/null +++ b/icm-contracts/README.md @@ -0,0 +1,95 @@ +# ICM Contracts + +For help getting started with building ICM contracts, refer to [the avalanche-starter-kit repository](https://github.com/ava-labs/avalanche-starter-kit). + +- [Setup](#setup) + - [Initialize the repository](#initialize-the-repository) + - [Dependencies](#dependencies) +- [Structure](#structure) +- [E2E tests](#e2e-tests) + - [Run specific E2E tests](#run-specific-e2e-tests) +- [ABI Bindings](#abi-bindings) +- [Docs](#docs) +- [Resources](#resources) + +## Setup + +### Initialize the repository + +- Get all submodules: `git submodule update --init --recursive` + +### Dependencies + +- [Ginkgo](https://onsi.github.io/ginkgo/#installing-ginkgo) for running the end-to-end tests. +- [Foundry](https://book.getfoundry.sh/) Use `./scripts/install_foundry.sh` to install Foundry for building contracts. + +## Structure + +- `contracts/` + - [`governance/`](./contracts/governance/README.md) includes contracts related to L1 governance. + - [`ictt/`](./contracts/ictt/README.md) Interchain Token Transfer contracts. Facilitates the transfer of tokens among L1s. + - [`teleporter/`](./contracts/teleporter/README.md) includes `TeleporterMessenger`, which serves as the interface for most contracts to use ICM. + - [`registry/`](./contracts/teleporter/registry/README.md) includes a registry contract for managing different versions of `TeleporterMessenger`. + - [`validator-manager/`](./contracts/validator-manager/README.md) includes contracts for managing the validator set of an L1. +- `abi-bindings/` includes Go ABI bindings for the contracts in `contracts/`. +- [`audits/`](./audits/README.md) includes all audits conducted on contracts in this repository. +- `tests/` includes integration tests for the contracts in `contracts/`, written using the [Ginkgo](https://onsi.github.io/ginkgo/) testing framework. +- `utils/` includes Go utility functions for interacting with the contracts in `contracts/`. Included are Golang scripts to derive the expected EVM contract address deployed from a given EOA at a specific nonce, and also construct a transaction to deploy provided byte code to the same address on any EVM chain using [Nick's method](https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c#). +- `scripts/` includes bash scripts for interacting with TeleporterMessenger in various environments, as well as utility scripts. + - `abi_bindings.sh` generates ABI bindings for the contracts in `contracts/` and outputs them to `abi-bindings/`. + - `lint.sh` performs Solidity and Golang linting. + +## E2E tests + +In addition to the docker setup, end-to-end integration tests written using Ginkgo are provided in the `tests/` directory. E2E tests are run as part of CI, but can also be run locally. Any new features or cross-chain example applications checked into the repository should be accompanied by an end-to-end tests. See the [Contribution Guide](./CONTRIBUTING.md) for additional details. + +To run the E2E tests locally, you'll need to install Gingko following the instructions [here](https://onsi.github.io/ginkgo/#installing-ginkgo). + +Then run the following command from the root of the repository: + +```bash +./scripts/contracts_e2e_test.sh +``` + +### Run specific E2E tests + +To run a specific E2E test, specify the environment variable `GINKGO_FOCUS`, which will then look for test descriptions that match the provided input. For example, to run the `Calculate Teleporter message IDs` test: + +```bash +GINKGO_FOCUS="Calculate Teleporter message IDs" ./scripts/contracts_e2e_test.sh +``` + +A substring of the full test description can be used as well: + +```bash +GINKGO_FOCUS="Calculate Teleporter" ./scripts/contracts_e2e_test.sh +``` + +The E2E test script also supports a `--components` flag, making it easy to run all the test cases for a particular project. For example, to run all E2E tests for the `tests/flows/ictt/` folder: + +```bash +./scripts/contracts_e2e_test.sh --components "ictt" +``` + +## ABI Bindings + +The E2E tests written in Golang interface with the solidity contracts by use of generated ABI bindings. To regenerate Golang ABI bindings for the Solidity smart contracts, run: + +```bash +./scripts/abi_bindings.sh +``` + +The auto-generated bindings should be written under the `abi-bindings/` directory. + +## Docs + +- [ICM Protocol Overview](./contracts/teleporter/README.md) +- [Teleporter Registry and Upgrades](./contracts/teleporter/registry/README.md) +- [Contract Deployment](./utils/contract-deployment/README.md) +- [Teleporter CLI](./cmd/teleporter-cli/README.md) + +## Resources + +- List of blockchain signing cryptography algorithms [here](http://ethanfast.com/top-crypto.html). +- Background on stateful precompiles [here](https://medium.com/avalancheavax/customizing-the-evm-with-stateful-precompiles-f44a34f39efd). +- Background on BLS signature aggregation [here](https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html). diff --git a/icm-contracts/audits/Ava Labs Validator Manager Incremental Audit (May 7th 2025) - OpenZeppelin.pdf b/icm-contracts/audits/Ava Labs Validator Manager Incremental Audit (May 7th 2025) - OpenZeppelin.pdf new file mode 100644 index 000000000..5dbaad683 Binary files /dev/null and b/icm-contracts/audits/Ava Labs Validator Manager Incremental Audit (May 7th 2025) - OpenZeppelin.pdf differ diff --git a/icm-contracts/audits/ICTT Audit (June 26th 2024) - OpenZeppelin.pdf b/icm-contracts/audits/ICTT Audit (June 26th 2024) - OpenZeppelin.pdf new file mode 100644 index 000000000..677603fe4 Binary files /dev/null and b/icm-contracts/audits/ICTT Audit (June 26th 2024) - OpenZeppelin.pdf differ diff --git a/icm-contracts/audits/README.md b/icm-contracts/audits/README.md new file mode 100644 index 000000000..d4fb28425 --- /dev/null +++ b/icm-contracts/audits/README.md @@ -0,0 +1,12 @@ +# Audits + +Below is the list of most recent audit for each smart contract application in this repository. Please exercise caution when using code newer than the audited commit. + +See `audits/historical` for older audits. These audits may now be obsolete, and legacy code superseded by new versions are __not__ recommended for production deployments. + +| Date | Commit | Auditor | Scope | Links | +| ------------ | ---------- | ------------ | -------------------- | ----------------------------------------------------------- | +| Nov 2023 | `6ba46565` | OpenZeppelin | All contracts in the top-level of `contracts/teleporter/` | [🔗](./Teleporter%20Audit%20(November%2016th%202023)%20-%20OpenZeppelin.pdf) | +| Jan 2024 | `9fcdf42d` | Louis | Some contracts in `contracts/teleporter/registry` and `contracts/utilities`, see audit for details | [🔗](./Teleporter%20Upgradeable%20Audit%20(January%2010th%202024)%20-%20Louis.pdf) | +| Jun 2024 | `9e03a1e5` | OpenZeppelin | All contracts in `contracts/ictt/` excluding `mocks/` | [🔗](./ICTT%20Audit%20(June%2026th%202024)%20-%20OpenZeppelin.pdf) | +| May 2025 | `93920df` | OpenZeppelin | All contracts in `contracts/validator-manager/` | [🔗](./Ava%20Labs%20Validator%20Manager%20Incremental%20Audit%20(May%207th%202025)%20-%20OpenZeppelin.pdf) | \ No newline at end of file diff --git a/icm-contracts/audits/Teleporter Audit (November 16th 2023) - OpenZeppelin.pdf b/icm-contracts/audits/Teleporter Audit (November 16th 2023) - OpenZeppelin.pdf new file mode 100644 index 000000000..9553df116 Binary files /dev/null and b/icm-contracts/audits/Teleporter Audit (November 16th 2023) - OpenZeppelin.pdf differ diff --git a/icm-contracts/audits/Teleporter Upgradeable Audit (January 10th 2024) - Louis.pdf b/icm-contracts/audits/Teleporter Upgradeable Audit (January 10th 2024) - Louis.pdf new file mode 100644 index 000000000..8908c90c3 Binary files /dev/null and b/icm-contracts/audits/Teleporter Upgradeable Audit (January 10th 2024) - Louis.pdf differ diff --git a/icm-contracts/audits/historical/Bridge Smart Contracts Audit Report (July 7th 2023) - Least Authority .pdf b/icm-contracts/audits/historical/Bridge Smart Contracts Audit Report (July 7th 2023) - Least Authority .pdf new file mode 100644 index 000000000..f416fc0d0 Binary files /dev/null and b/icm-contracts/audits/historical/Bridge Smart Contracts Audit Report (July 7th 2023) - Least Authority .pdf differ diff --git a/icm-contracts/audits/historical/Teleporter Audit (October 20 2023) - Louis.pdf b/icm-contracts/audits/historical/Teleporter Audit (October 20 2023) - Louis.pdf new file mode 100644 index 000000000..a0a7460d4 Binary files /dev/null and b/icm-contracts/audits/historical/Teleporter Audit (October 20 2023) - Louis.pdf differ diff --git a/icm-contracts/audits/historical/Validator Manager Audit (October 30th 2024) - OpenZeppelin.pdf b/icm-contracts/audits/historical/Validator Manager Audit (October 30th 2024) - OpenZeppelin.pdf new file mode 100644 index 000000000..5bb5e3e8f Binary files /dev/null and b/icm-contracts/audits/historical/Validator Manager Audit (October 30th 2024) - OpenZeppelin.pdf differ diff --git a/icm-contracts/cmd/teleporter-cli/README.md b/icm-contracts/cmd/teleporter-cli/README.md new file mode 100644 index 000000000..f3252e1b3 --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/README.md @@ -0,0 +1,17 @@ +# Teleporter CLI + +This directory contains the source code for the Teleporter CLI. The CLI is a command line interface for interacting with the Teleporter contracts. It is written with [cobra](https://github.com/spf13/cobra) commands as a Go application. + +## Build + +To build the CLI, run `go build` from this directory. This will create a binary called `teleporter-cli` in the current directory. + +## Usage + +The CLI has a number of subcommands. To see the list of subcommands, run `./teleporter-cli help`. To see the help for a specific subcommand, run `./teleporter-cli help `. + +The supported subcommands include: + +- `event`: given a log event's topics and data, attempts to decode into a Teleporter event in a more readable format. +- `message`: given a Teleporter message encoded as a hex string, attempts to decode into a Teleporter message in a more readable format. +- `transaction`: given a transaction hash, attempts to decode all relevant TeleporterMessenger and ICM log events in a more readable format. diff --git a/icm-contracts/cmd/teleporter-cli/event.go b/icm-contracts/cmd/teleporter-cli/event.go new file mode 100644 index 000000000..e59000144 --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/event.go @@ -0,0 +1,50 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + "github.com/ava-labs/libevm/common" + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +var ( + topicArgs []string + data []byte +) + +var eventCmd = &cobra.Command{ + Use: "event --topics topic1,topic2 [--data data]", + Short: "Parses a Teleporter log's topics and data", + Long: `Given the topics and data of a Teleporter log, parses the log into +the corresponding Teleporter event. Topics are represented by a hash, +and data is the hex encoding of the bytes.`, + Args: cobra.NoArgs, + Run: eventRun, +} + +func eventRun(cmd *cobra.Command, args []string) { + var topics []common.Hash + for _, topic := range topicArgs { + topics = append(topics, common.HexToHash(topic)) + } + + event, err := teleporterABI.EventByID(topics[0]) + cobra.CheckErr(err) + + out, err := teleportermessenger.FilterTeleporterEvents(topics, data, event.Name) + cobra.CheckErr(err) + logger.Info("Parsed Teleporter event", zap.String("name", event.Name), zap.String("event", out.String())) + cmd.Println("Event command ran successfully for", event.Name) +} + +func init() { + rootCmd.AddCommand(eventCmd) + eventCmd.PersistentFlags().StringSliceVar(&topicArgs, "topics", []string{}, "Topic hashes of the event") + eventCmd.Flags().BytesHexVar(&data, "data", []byte{}, "Hex encoded data of the event") + + err := eventCmd.MarkPersistentFlagRequired("topics") + cobra.CheckErr(err) +} diff --git a/icm-contracts/cmd/teleporter-cli/event_test.go b/icm-contracts/cmd/teleporter-cli/event_test.go new file mode 100644 index 000000000..7cdc808d8 --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/event_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestEventCmd(t *testing.T) { + var tests = []struct { + name string + args []string + err error + out string + }{ + { + name: "no args", + args: []string{"event"}, + err: fmt.Errorf("required flag(s) \"topics\" not set"), + }, + { + name: "help", + args: []string{"event", "--help"}, + err: nil, + out: "Given the topics and data of a Teleporter log", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, err := executeTestCmd(t, rootCmd, tt.args...) + if tt.err != nil { + require.ErrorContains(t, err, tt.err.Error()) + } else { + require.NoError(t, err) + require.Contains(t, out, tt.out) + } + }) + } +} diff --git a/icm-contracts/cmd/teleporter-cli/message.go b/icm-contracts/cmd/teleporter-cli/message.go new file mode 100644 index 000000000..e9d2bdece --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/message.go @@ -0,0 +1,35 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "encoding/hex" + + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +var messageCmd = &cobra.Command{ + Use: "message MESSAGE_BYTES", + Short: "Decodes hex encoded TeleporterMessenger message bytes into a TeleporterMessage struct", + Long: `Given the hex encoded bytes of a TeleporterMessenger message, this command will decode +the bytes into a TeleporterMessage struct and print the struct fields.`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + encodedMsg := args[0] + b, err := hex.DecodeString(encodedMsg) + cobra.CheckErr(err) + + msg := teleportermessenger.TeleporterMessage{} + err = msg.Unpack(b) + cobra.CheckErr(err) + logger.Info("TeleporterMessenger Message unpacked", zap.Any("message", msg)) + cmd.Println("Message command ran successfully") + }, +} + +func init() { + rootCmd.AddCommand(messageCmd) +} diff --git a/icm-contracts/cmd/teleporter-cli/message_test.go b/icm-contracts/cmd/teleporter-cli/message_test.go new file mode 100644 index 000000000..d4fe5b397 --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/message_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMessageCmd(t *testing.T) { + var tests = []struct { + name string + args []string + err error + out string + }{ + { + name: "no args", + args: []string{"message"}, + err: fmt.Errorf("accepts 1 arg(s), received 0"), + }, + { + name: "help", + args: []string{"message", "--help"}, + err: nil, + out: "Given the hex encoded bytes of a TeleporterMessenger message", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, err := executeTestCmd(t, rootCmd, tt.args...) + if tt.err != nil { + require.ErrorContains(t, err, tt.err.Error()) + } else { + require.NoError(t, err) + require.Contains(t, out, tt.out) + } + }) + } +} diff --git a/icm-contracts/cmd/teleporter-cli/root.go b/icm-contracts/cmd/teleporter-cli/root.go new file mode 100644 index 000000000..f3b876d37 --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/root.go @@ -0,0 +1,81 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "os" + + "github.com/ava-labs/avalanchego/utils/logging" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/spf13/cobra" +) + +var ( + logger logging.Logger + teleporterABI *abi.ABI +) + +var rootCmd = &cobra.Command{ + Use: "teleporter-cli", + Short: "A CLI that integrates with the Teleporter protocol", + Long: `A CLI that integrates with the Teleporter protocol, and allows you +to debug Teleporter on chain activity. The CLI can help decode +TeleporterMessenger and ICM events, as well as parsing Teleporter messages.`, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + rootCmd.CompletionOptions.DisableDefaultCmd = true + logLevelArg := rootCmd.PersistentFlags().StringP("log", "l", "", "Log level i.e. debug, info...") + rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { + return rootPreRunE(logLevelArg) + } +} + +func rootPreRunE(logLevelArg *string) error { + if *logLevelArg == "" { + *logLevelArg = logging.Info.LowerString() + } + + logLevel, err := logging.ToLevel(*logLevelArg) + if err != nil { + return err + } + logger = logging.NewLogger( + "teleporter-cli", + logging.NewWrappedCore( + logLevel, + os.Stdout, + logging.Plain.ConsoleEncoder(), + ), + ) + abi, err := teleportermessenger.TeleporterMessengerMetaData.GetAbi() + if err != nil { + return err + } + teleporterABI = abi + return nil +} + +func callPersistentPreRunE(cmd *cobra.Command, args []string) error { + if parent := cmd.Parent(); parent != nil { + if parent.PersistentPreRunE != nil { + return parent.PersistentPreRunE(parent, args) + } + } + return nil +} + +func main() { + Execute() +} diff --git a/icm-contracts/cmd/teleporter-cli/root_test.go b/icm-contracts/cmd/teleporter-cli/root_test.go new file mode 100644 index 000000000..d9cbac65f --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/root_test.go @@ -0,0 +1,60 @@ +package main + +import ( + "bytes" + "fmt" + "strings" + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/require" +) + +func executeTestCmd(t *testing.T, c *cobra.Command, args ...string) (string, error) { + buf := new(bytes.Buffer) + c.SetOut(buf) + c.SetErr(buf) + c.SetArgs(args) + + err := c.Execute() + return strings.TrimSpace(buf.String()), err +} + +func TestRootCmd(t *testing.T) { + var tests = []struct { + name string + args []string + err error + out string + }{ + { + name: "base", + args: []string{}, + err: nil, + out: "A CLI that integrates with the Teleporter protocol", + }, + { + name: "help", + args: []string{"--help"}, + err: nil, + out: "A CLI that integrates with the Teleporter protocol", + }, + { + name: "invalid", + args: []string{"invalid"}, + err: fmt.Errorf("unknown command"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, err := executeTestCmd(t, rootCmd, tt.args...) + if tt.err != nil { + require.ErrorContains(t, err, tt.err.Error()) + } else { + require.NoError(t, err) + require.Contains(t, out, tt.out) + } + }) + } +} diff --git a/icm-contracts/cmd/teleporter-cli/transaction.go b/icm-contracts/cmd/teleporter-cli/transaction.go new file mode 100644 index 000000000..97a53410b --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/transaction.go @@ -0,0 +1,157 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "context" + "encoding/json" + + warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/eth/tracers" + "github.com/ava-labs/subnet-evm/ethclient" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + "github.com/spf13/cobra" +) + +const ( + ICMPrecompileAddressHex = "0x0200000000000000000000000000000000000005" +) + +var ( + debug bool + rpcEndpoint string + teleporterAddress common.Address + client ethclient.Client +) + +var transactionCmd = &cobra.Command{ + Use: "transaction --rpc RPC_URL --teleporter-address CONTRACT_ADDRESS TRANSACTION_HASH", + Short: "Parses relevant Teleporter logs from a transaction", + Long: `Given a transaction this command looks through the transaction's receipt +for TeleporterMessenger and ICM log events. When corresponding log events are found, +the command parses to log event fields to a more human readable format. Optionally pass -d +or --debug for extra transaction output. This may require enabling debug enpoints on your RPC node`, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + txHash := common.HexToHash(args[0]) + if debug { + printTransaction(cmd, txHash) + traceTransaction(cmd, txHash) + } + checkReceipt(cmd, txHash) + cmd.Println("Transaction command ran successfully") + }, +} + +func checkReceipt(cmd *cobra.Command, txHash common.Hash) { + receipt, err := client.TransactionReceipt(context.Background(), txHash) + cobra.CheckErr(err) + + ICMPrecompileAddress := common.HexToAddress(ICMPrecompileAddressHex) + for _, log := range receipt.Logs { + switch log.Address { + case teleporterAddress: + printTeleporterLogs(cmd, log) + case ICMPrecompileAddress: + printICMLogs(cmd, log) + } + } +} + +func printTeleporterLogs(cmd *cobra.Command, log *types.Log) { + logJson, err := json.MarshalIndent(log, "", " ") + cobra.CheckErr(err) + + cmd.Println("Teleporter Log:\n" + string(logJson) + "\n") + + event, err := teleporterABI.EventByID(log.Topics[0]) + cobra.CheckErr(err) + + out, err := teleportermessenger.FilterTeleporterEvents(log.Topics, log.Data, event.Name) + cobra.CheckErr(err) + + cmd.Println(event.Name + " Log:") + cmd.Println(out.String() + "\n") +} + +func printICMLogs(cmd *cobra.Command, log *types.Log) { + logJson, err := json.MarshalIndent(log, "", " ") + cobra.CheckErr(err) + + cmd.Println("ICM Log:\n" + string(logJson) + "\n") + + unsignedMsg, err := warp.UnpackSendWarpEventDataToMessage(log.Data) + cobra.CheckErr(err) + cmd.Println("ICM Message ID: " + unsignedMsg.ID().Hex()) + + icmPayload, err := warpPayload.ParseAddressedCall(unsignedMsg.Payload) + cobra.CheckErr(err) + + icmPayloadJson, err := json.MarshalIndent(icmPayload, "", " ") + cobra.CheckErr(err) + cmd.Println("ICM Payload:") + cmd.Println(string(icmPayloadJson)) + + teleporterMessage := teleportermessenger.TeleporterMessage{} + err = teleporterMessage.Unpack(icmPayload.Payload) + cobra.CheckErr(err) + + cmd.Println("Teleporter Message:") + cmd.Println(teleporterMessage.String()) +} + +func traceTransaction(cmd *cobra.Command, txHash common.Hash) { + var result interface{} + ct := "callTracer" + err := client.Client().Call(&result, "debug_traceTransaction", txHash.String(), tracers.TraceConfig{Tracer: &ct}) + if err != nil { + cmd.PrintErr("Error calling debug_traceTransaction: " + err.Error()) + return + } + json, err := json.MarshalIndent(result, "", " ") + cobra.CheckErr(err) + + cmd.Println("Transaction Trace:\n" + string(json) + "\n") +} + +func printTransaction(cmd *cobra.Command, txHash common.Hash) { + tx, _, err := client.TransactionByHash(context.Background(), txHash) + cobra.CheckErr(err) + json, err := json.MarshalIndent(tx, "", " ") + cobra.CheckErr(err) + + cmd.Println("Transaction:\n" + string(json) + "\n") +} + +func init() { + rootCmd.AddCommand(transactionCmd) + transactionCmd.PersistentFlags().StringVar(&rpcEndpoint, "rpc", "", "RPC endpoint to connect to the node") + address := transactionCmd.PersistentFlags().StringP("teleporter-address", "t", "", "Teleporter contract address") + err := transactionCmd.MarkPersistentFlagRequired("rpc") + cobra.CheckErr(err) + err = transactionCmd.MarkPersistentFlagRequired("teleporter-address") + cobra.CheckErr(err) + transactionCmd.Flags().BoolVarP(&debug, "debug", "d", false, "default: false.") + transactionCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { + return transactionPreRunE(cmd, args, address) + } +} + +func transactionPreRunE(cmd *cobra.Command, args []string, address *string) error { + // Run the persistent pre-run function of the root command if it exists. + if err := callPersistentPreRunE(cmd, args); err != nil { + return err + } + teleporterAddress = common.HexToAddress(*address) + c, err := ethclient.Dial(rpcEndpoint) + if err != nil { + return err + } + + client = c + return nil +} diff --git a/icm-contracts/cmd/teleporter-cli/transaction_test.go b/icm-contracts/cmd/teleporter-cli/transaction_test.go new file mode 100644 index 000000000..ad1371ac7 --- /dev/null +++ b/icm-contracts/cmd/teleporter-cli/transaction_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTransactionCmd(t *testing.T) { + var tests = []struct { + name string + args []string + err error + out string + }{ + { + name: "no args", + args: []string{"transaction"}, + err: fmt.Errorf("accepts 1 arg(s), received 0"), + }, + { + name: "help", + args: []string{"transaction", "--help"}, + err: nil, + out: "Given a transaction this command looks through the transaction's receipt", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, err := executeTestCmd(t, rootCmd, tt.args...) + if tt.err != nil { + require.ErrorContains(t, err, tt.err.Error()) + } else { + require.NoError(t, err) + require.Contains(t, out, tt.out) + } + }) + } +} diff --git a/icm-contracts/contracts/README.md b/icm-contracts/contracts/README.md new file mode 100644 index 000000000..1536ea362 --- /dev/null +++ b/icm-contracts/contracts/README.md @@ -0,0 +1,19 @@ +# Contracts + +This directory contains Solidity contracts that leverage Avalanche Interchain Messaging (ICM) to implement unique cross-chain functions. + +This repository is set up as a [Foundry](https://github.com/foundry-rs/foundry) project. Use the `scripts/install_foundry.sh` to install the correct version of Foundry. + +## Building and Running + +- To compile the contracts run `forge build` from this directory. +- Similarly, to run unit tests, run `forge test`. +- See additional testing and deployment options [here](https://book.getfoundry.sh/forge/). + +## Generate documentation + +- Documentation can be generated by running `forge doc --build` from this repository. By default, this will generate documentation to `contracts/docs/`, and an HTML book to `contracts/docs/book/`. It's also possible to serve this book locally by running `forge doc --serve `. + +## Audits + +In general, the contracts in this repository have been audited. Any contracts that have not undergone at least one audit will be explicitly marked as such. Please note that audits capture the state of code at a point in time, and the code is subject to change in the meantime. Please check [here](../audits/README.md) for the full list of audits. diff --git a/icm-contracts/contracts/governance/README.md b/icm-contracts/contracts/governance/README.md new file mode 100644 index 000000000..9fd06683d --- /dev/null +++ b/icm-contracts/contracts/governance/README.md @@ -0,0 +1,18 @@ +# Governance Contracts + +## Overview + +This contract provides an alternative to traditional multi-signature contracts where instead of requiring signatures from `K` of `N` pre-specified signers, an aggregate signature is required from a quorum of the current validators for a given blockchain. + +The contract leverages off-chain [Avalanche ICM Messages](https://docs.avax.network/build/cross-chain/awm/overview), which are manually approved for signing by a chain's validators. It requires these messages to have the source address set to the zero address to enforce this, since on-chain ICM messages cannot have zero source address. + +Note: +1. The blockchain validating the message may or may not be the same chain where the target contract and the `ValidatorSetSig` contract are deployed. +2. [Off-Chain ICM messages](https://github.com/ava-labs/subnet-evm/issues/729) are ICM messages that validators can include in their config to indicate that they are willing to sign them even though they are not a result of on-chain activity. + +#### Creating a valid Off-chain ICM Message for interaction with the ValidatorSetSig Contract + +1. ABI-encode a `ValidatorSetSigMessage` as defined in `ValidatorSetSig.sol` +2. OPTIONAL: call `validateMessage` view method of the intended contract to confirm that the message has correct fields, including the nonce. +3. Pack that as the payload of an [AddressedCall](https://github.com/ava-labs/avalanchego/blob/0c4efd743e1d737f4e8970d0e0ebf229ea44406c/vms/platformvm/warp/payload/addressed_call.go#L15) ICM Message format. Note that the `SourceAddress` field has to be set to the zero address. +4. Pack the `AddressedCall` as the payload of the [UnsignedWarpMessage](https://github.com/ava-labs/avalanchego/blob/f17ea6a7ab4036c41b693e47b94d8f0c81cb69ec/vms/platformvm/warp/unsigned_message.go#L14). diff --git a/icm-contracts/contracts/governance/ValidatorSetSig.sol b/icm-contracts/contracts/governance/ValidatorSetSig.sol new file mode 100644 index 000000000..89e694cd9 --- /dev/null +++ b/icm-contracts/contracts/governance/ValidatorSetSig.sol @@ -0,0 +1,146 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {WarpMessage, IWarpMessenger} from "@subnet-evm/IWarpMessenger.sol"; +import {ReentrancyGuard} from "@openzeppelin/contracts@5.0.2/utils/ReentrancyGuard.sol"; + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + * DO NOT USE THIS CODE IN PRODUCTION. + */ + +/** + * @dev Message format for the WarpMessage payload to be forwarded to the target contract + * + * targetBlockchainID: Blockchain ID of the chain the message is intended for + * validatorSetSigAddress: Address of the ValidatorSetSig contract this message is intended for + * targetContractAddress: Address of the contract that the payload should be forwarded to + * nonce: Unique nonce for the target contract address to provide replay protection + * value: Value to be sent with the call to the target contract + * payload: Payload to be forwarded to the target contract. Usually ABI encoded function call with parameters. + */ +struct ValidatorSetSigMessage { + bytes32 targetBlockchainID; + address validatorSetSigAddress; + address targetContractAddress; + uint256 nonce; + uint256 value; + bytes payload; +} + +/** + * @dev Contract that verifies that a set threshold of validators from a given blockchainID + * have signed an off-chain ICM message and forwards the payload to the target contract specified in the ValidatorSetSigMessage. + * The threshold itself is set by the validator themselves in their ICM configs: + * https://github.com/ava-labs/subnet-evm/blob/6c018f89339f3d381909e02013f002f234dc7ae3/precompile/contracts/warp/config.go#L50 + * + * This is intended to be used for safe off-chain governance of enabled contracts. An example use case would be + * to deploy an `Ownable` target contract that is owned by an instance of this contract and adding the + * `onlyOwner` modifier to the functions that should be governed. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract ValidatorSetSig is ReentrancyGuard { + /** + * @notice Address that the off-chain ICM message sets as the "source" address. + * @dev The address is not owned by any EOA or smart contract account, so it + * cannot possibly be the source address of any other ICM message emitted by the VM. + */ + address public constant VALIDATORS_SOURCE_ADDRESS = address(0); + + /** + * @notice ICM precompile used for sending and receiving ICM messages. + */ + IWarpMessenger public constant WARP_MESSENGER = + IWarpMessenger(0x0200000000000000000000000000000000000005); + + /** + * @notice A blockchain ID whose validators need to sign the message for it to be considered valid. + */ + bytes32 public immutable validatorBlockchainID; + + /** + * @notice The blockchain ID of the chain the contract is deployed on. + */ + bytes32 public immutable blockchainID; + + /** + * @dev Tracks nonces for messages sent to a specific contract address to provide replay protection. + * The target contract address is used as the key instead of keeping a global nonce to prevent + * one party from consuming a global nonce that another was intending to use + * in case a single instance of ValidatorSetSig contract is used to manage multiple downstream contracts. + */ + mapping(address targetContractAddress => uint256 nonce) public nonces; + + /** + * @notice Emited when the payload is successfully delivered to the target contract. + */ + event Delivered(address indexed targetContractAddress, uint256 indexed nonce); + + constructor( + bytes32 validatorBlockchainID_ + ) { + validatorBlockchainID = validatorBlockchainID_; + blockchainID = WARP_MESSENGER.getBlockchainID(); + } + + receive() external payable {} + + function executeCall( + uint32 messageIndex + ) external payable nonReentrant { + // Get the WarpMessage from the WarpMessenger precompile and verify that it is valid + (WarpMessage memory message, bool valid) = + WARP_MESSENGER.getVerifiedWarpMessage(messageIndex); + require(valid, "ValidatorSetSig: invalid warp message"); + + // Ensure that the sourceChainID of the validator set that signed the message is the authorized one + require( + message.sourceChainID == validatorBlockchainID, "ValidatorSetSig: invalid sourceChainID" + ); + // Ensure that the originSenderAddress is the zero address to prevent on-chain messages from being forwarded + require( + message.originSenderAddress == VALIDATORS_SOURCE_ADDRESS, + "ValidatorSetSig: non-zero originSenderAddress" + ); + + ValidatorSetSigMessage memory validatorSetSigMessage = + abi.decode(message.payload, (ValidatorSetSigMessage)); + + validateMessage(validatorSetSigMessage); + + nonces[validatorSetSigMessage.targetContractAddress] = validatorSetSigMessage.nonce + 1; + + // We don't need to protect against return bomb vectors below here since the caller is expected to have full control over the contract called. + ( + bool success, // solhint-disable-next-line avoid-low-level-calls + ) = validatorSetSigMessage.targetContractAddress.call{value: validatorSetSigMessage.value}( + validatorSetSigMessage.payload + ); + + // Use require to revert the transaction if the call fails. This is to prevent consuming the nonce if the call fails due to out of gas + // and requiring re-signing of the message with a new nonce. + require(success, "ValidatorSetSig: call failed"); + emit Delivered(validatorSetSigMessage.targetContractAddress, validatorSetSigMessage.nonce); + } + + function validateMessage( + ValidatorSetSigMessage memory message + ) public view { + require( + message.targetBlockchainID == blockchainID, + "ValidatorSetSig: invalid targetBlockchainID" + ); + require( + message.validatorSetSigAddress == address(this), + "ValidatorSetSig: invalid validatorSetSigAddress" + ); + require( + nonces[message.targetContractAddress] == message.nonce, "ValidatorSetSig: invalid nonce" + ); + } +} diff --git a/icm-contracts/contracts/governance/tests/ValidatorSetSigTests.t.sol b/icm-contracts/contracts/governance/tests/ValidatorSetSigTests.t.sol new file mode 100644 index 000000000..e658a68d6 --- /dev/null +++ b/icm-contracts/contracts/governance/tests/ValidatorSetSigTests.t.sol @@ -0,0 +1,288 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import { + ValidatorSetSig, + WarpMessage, + IWarpMessenger, + ValidatorSetSigMessage +} from "../ValidatorSetSig.sol"; + +import {UnitTestMockERC20} from "@mocks/UnitTestMockERC20.sol"; + +contract ValidatorSetSigTest is Test { + address public constant WARP_PRECOMPILE_ADDRESS = + address(0x0200000000000000000000000000000000000005); + bytes32 private constant _MOCK_BLOCKCHAIN_ID = bytes32(uint256(123456)); + bytes32 private constant _MOCK_VALIDATOR_CHAIN_ID = bytes32(uint256(234567)); + address private constant _DEFAULT_TARGET_ADDRESS = 0x1234512345123451234512345123451234512345; + address private constant _OTHER_TARGET_ADDRESS = 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + address private constant _ERC20_RECIPIENT_ADDRESS = 0xa4CEE7d1aF6aDdDD33E3b1cC680AB84fdf1b6d1d; + + ValidatorSetSig public validatorSetSig; + UnitTestMockERC20 public mockERC20; + + function setUp() public virtual { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(_MOCK_BLOCKCHAIN_ID) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector) + ); + + validatorSetSig = new ValidatorSetSig(_MOCK_VALIDATOR_CHAIN_ID); + assertEq(validatorSetSig.blockchainID(), _MOCK_BLOCKCHAIN_ID); + assertEq(validatorSetSig.validatorBlockchainID(), _MOCK_VALIDATOR_CHAIN_ID); + + mockERC20 = new UnitTestMockERC20(); + mockERC20.transfer(_ERC20_RECIPIENT_ADDRESS, 10); + assertEq(mockERC20.balanceOf(_ERC20_RECIPIENT_ADDRESS), 10); + } + + function testInvalidMessage() public { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(_getValidWarpMessage(), false) + ); + vm.expectRevert("ValidatorSetSig: invalid warp message"); + validatorSetSig.executeCall(0); + } + + function testInvalidSourceChainID() public { + WarpMessage memory invalidSourceChainMessage = _getValidWarpMessage(); + invalidSourceChainMessage.sourceChainID = _MOCK_BLOCKCHAIN_ID; + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(invalidSourceChainMessage, true) + ); + vm.expectRevert("ValidatorSetSig: invalid sourceChainID"); + validatorSetSig.executeCall(0); + } + + function testNonZeroSourceAddress() public { + WarpMessage memory nonZeroSourceAddressMessage = _getValidWarpMessage(); + nonZeroSourceAddressMessage.originSenderAddress = address(1); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(nonZeroSourceAddressMessage, true) + ); + vm.expectRevert("ValidatorSetSig: non-zero originSenderAddress"); + validatorSetSig.executeCall(0); + } + + function testInvalidValidatorSetSigContractAddress() public { + WarpMessage memory invalidValidatorSetSigContractAddressMessage = _getValidWarpMessage(); + ValidatorSetSigMessage memory validatorSetSigMessage = _getValidValidatorSetSigMessage(); + validatorSetSigMessage.validatorSetSigAddress = address(1); + invalidValidatorSetSigContractAddressMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(invalidValidatorSetSigContractAddressMessage, true) + ); + vm.expectRevert("ValidatorSetSig: invalid validatorSetSigAddress"); + validatorSetSig.executeCall(0); + } + + function testInvalidTargetBlockChainID() public { + WarpMessage memory invalidTargetBlockChainIDMessage = _getValidWarpMessage(); + ValidatorSetSigMessage memory validatorSetSigMessage = _getValidValidatorSetSigMessage(); + validatorSetSigMessage.targetBlockchainID = _MOCK_VALIDATOR_CHAIN_ID; + invalidTargetBlockChainIDMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(invalidTargetBlockChainIDMessage, true) + ); + vm.expectRevert("ValidatorSetSig: invalid targetBlockchainID"); + validatorSetSig.executeCall(0); + } + + function testNonces() public { + WarpMessage memory warpMessage = _getValidWarpMessage(); + ValidatorSetSigMessage memory validatorSetSigMessage = _getValidValidatorSetSigMessage(); + // Set nonce to invalid value, since first message should have nonce 0 + validatorSetSigMessage.nonce = 1; + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + vm.expectRevert("ValidatorSetSig: invalid nonce"); + validatorSetSig.executeCall(0); + // Set nonce to 2 which is still invalid and verify that it still fails + validatorSetSigMessage.nonce = 2; + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + vm.expectRevert("ValidatorSetSig: invalid nonce"); + validatorSetSig.executeCall(0); + + // Set nonce to 0 which is valid + validatorSetSigMessage.nonce = 0; + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + assertEq(validatorSetSig.nonces(_DEFAULT_TARGET_ADDRESS), 0); + validatorSetSig.executeCall(0); + assertEq(validatorSetSig.nonces(_DEFAULT_TARGET_ADDRESS), 1); + + // Set nonce to 1 which is valid + validatorSetSigMessage.nonce = 1; + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + validatorSetSig.executeCall(0); + assertEq(validatorSetSig.nonces(_DEFAULT_TARGET_ADDRESS), 2); + + // finally test different target address + validatorSetSigMessage.targetContractAddress = _OTHER_TARGET_ADDRESS; + validatorSetSigMessage.nonce = 0; + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + validatorSetSig.executeCall(0); + assertEq(validatorSetSig.nonces(_DEFAULT_TARGET_ADDRESS), 2); + assertEq(validatorSetSig.nonces(_OTHER_TARGET_ADDRESS), 1); + } + + function testReentrancy() public { + WarpMessage memory warpMessage = _getValidWarpMessage(); + ValidatorSetSigMessage memory validatorSetSigMessage = _getValidValidatorSetSigMessage(); + // Set the targetContractAddress and the txPayload to the ValidatorSetSig contract itself + validatorSetSigMessage.payload = + abi.encodeWithSelector(validatorSetSig.executeCall.selector, uint32(0)); + validatorSetSigMessage.targetContractAddress = address(validatorSetSig); + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + // Checking for the outermost revert message since the reentrancy guard happens inside the call + vm.expectRevert("ValidatorSetSig: call failed"); + validatorSetSig.executeCall(0); + } + + function testInvalidValue() public { + WarpMessage memory warpMessage = _getValidWarpMessage(); + ValidatorSetSigMessage memory validatorSetSigMessage = _getValidValidatorSetSigMessage(); + + validatorSetSigMessage.value = 2; + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + // confirm that the current balance of both target address and the ValidatorSetSig contract is 0 + assertEq(_DEFAULT_TARGET_ADDRESS.balance, 0); + assertEq(address(validatorSetSig).balance, 0); + + // This should fail since the value in the message is 1 and the value in the call doesn't supply any native token + // nor is any available. + vm.expectRevert("ValidatorSetSig: call failed"); + validatorSetSig.executeCall(0); + + // This time the value in the message is 2 and the value in the call is 1, so it should revert + // since it's insufficient for the call + vm.expectRevert("ValidatorSetSig: call failed"); + validatorSetSig.executeCall{value: 1}(0); + + // Fund the ValidatorSetSig contract with one native token + address sender = address(0x1234); + vm.deal(sender, 3); + // Set the next msg.sender to be the sender address + vm.prank(sender); + (bool success,) = payable(validatorSetSig).call{value: 1}(""); + assertTrue(success); + assertEq(address(validatorSetSig).balance, 1); + + // This time it should succeed since message requires value to be 2 and the call supplies 1 directly + // and the remaining 1 from the contract balance + validatorSetSig.executeCall{value: 1}(0); + assertEq(_DEFAULT_TARGET_ADDRESS.balance, 2); + assertEq(address(validatorSetSig).balance, 0); + + // Update nonce to 1 and value to 3 + validatorSetSigMessage.nonce = 1; + validatorSetSigMessage.value = 3; + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(1)), + abi.encode(warpMessage, true) + ); + + // This time supply more (4) than required (3) and it should succeed and leave 1 in the contract + validatorSetSig.executeCall{value: 4}(1); + assertEq(_DEFAULT_TARGET_ADDRESS.balance, 5); + assertEq(address(validatorSetSig).balance, 1); + } + + // Uses the validatorSetSig contract to call the mockERC20 contract + // and verifies that the balance got updated correctly + function testSuccess() public { + WarpMessage memory warpMessage = _getValidWarpMessage(); + ValidatorSetSigMessage memory validatorSetSigMessage = _getValidValidatorSetSigMessage(); + // Set the targetContractAddress and the txPayload to the mockERC20 contract + validatorSetSigMessage.targetContractAddress = address(mockERC20); + validatorSetSigMessage.payload = + abi.encodeWithSelector(mockERC20.transfer.selector, _ERC20_RECIPIENT_ADDRESS, 5); + warpMessage.payload = abi.encode(validatorSetSigMessage); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode(warpMessage, true) + ); + assertEq(mockERC20.balanceOf(_ERC20_RECIPIENT_ADDRESS), 10); + validatorSetSig.executeCall(0); + assertEq(mockERC20.balanceOf(_ERC20_RECIPIENT_ADDRESS), 15); + } + + function _getValidWarpMessage() private view returns (WarpMessage memory) { + return WarpMessage({ + sourceChainID: _MOCK_VALIDATOR_CHAIN_ID, + originSenderAddress: address(0), + payload: abi.encode(_getValidValidatorSetSigMessage()) + }); + } + + function _getValidValidatorSetSigMessage() + private + view + returns (ValidatorSetSigMessage memory) + { + return ValidatorSetSigMessage({ + targetBlockchainID: _MOCK_BLOCKCHAIN_ID, + validatorSetSigAddress: address(validatorSetSig), + targetContractAddress: _DEFAULT_TARGET_ADDRESS, + nonce: 0, + value: 0, + payload: "" + }); + } +} diff --git a/icm-contracts/contracts/ictt/README.md b/icm-contracts/contracts/ictt/README.md new file mode 100644 index 000000000..f825bad1b --- /dev/null +++ b/icm-contracts/contracts/ictt/README.md @@ -0,0 +1,87 @@ +# Avalanche Interchain Token Transfer (ICTT) + +## Overview + +Avalanche Interchain Token Transfer (ICTT) is an application that allows users to transfer tokens between L1s. The implementation is a set of smart contracts that are deployed across multiple L1s, and leverages [ICM](https://github.com/ava-labs/icm-contracts) for cross-chain communication. + +Each token transferrer instance consists of one "home" contract and at least one but possibly many "remote" contracts. Each home contract instance manages one asset to be transferred out to `TokenRemote` instances. The home contract lives on the L1 where the asset to be transferred exists. A transfer consists of locking the asset as collateral on the home L1 and minting a representation of the asset on the remote L1. The remote contracts, each of which has a single specified home contract, live on other L1s that want to import the asset transferred by their specified home. The token transferrers are designed to be permissionless: anyone can register compatible `TokenRemote` instances to allow for transferring tokens from the `TokenHome` instance to that new `TokenRemote` instance. The home contract keeps track of token balances transferred to each `TokenRemote` instance, and handles returning the original tokens back to the user when assets are transferred back to the `TokenHome` instance. `TokenRemote` instances are registered with their home contract via an ICM message upon creation. + +Home contract instances specify the asset to be transferred as either an ERC20 token or the native token, and they allow for transferring the token to any registered `TokenRemote` instances. The token representation on the remote chain can also either be an ERC20 or native token, allowing users to have any combination of ERC20 and native tokens between home and remote chains: + +- `ERC20` -> `ERC20` +- `ERC20` -> `Native` +- `Native` -> `ERC20` +- `Native` -> `Native` + +The remote tokens are designed to have compatibility with the token transferrer on the home chain by default, and they allow custom logic to be implemented in addition. For example, developers can inherit and extend the `ERC20TokenRemote` contract to add additional functionality, such as a custom minting, burning, or transfer logic. + +The token transferrer also supports "multi-hop" transfers, where tokens can be transferred between remote chains. To illustrate, consider two remotes _Ra_ and _Rb_ that are both connected to the same home _H_. A multi-hop transfer from _Ra_ to _Rb_ first gets routed from _Ra_ to _H_, where remote balances are updated, and then _H_ automatically routes the transfer on to _Rb_. + +In addition to supporting basic token transfers, the token transferrer contracts offer a `sendAndCall` interface for transferring tokens and using them in a smart contract interaction all within a single ICM message. If the call to the recipient smart contract fails, the transferred tokens are sent to a fallback recipient address on the destination chain of the transfer. The `sendAndCall` interface enables the direct use of transferred tokens in dApps on other chains, such as performing swaps, using the tokens to pay for fees when invoking services, etc. + +## Upgradability + +The token transferrer contracts implement both upgradeable and non-upgradeable versions. The non-upgradeable versions are extensions of their respective upgradeable token transferrer contract, and has a `constructor` that calls the `initialize` function of the upgradeable version. The upgradeable contracts are ERC7201 compliant, and use namespace storage to store the state of the contract. + +## `ITokenTransferrer` + +Interface that defines the events token transfer contract implementations must emit. Also defines the message types and formats of messages between all implementations. + +## `IERC20TokenTransferrer` and `INativeTokenTransferrer` + +Interfaces that define the external functions for interacting with token transfer contract implementations of each type. ERC20 and native token transferrer interfaces vary from each other in that the native token transferrer functions are `payable` and do not take an explicit amount parameter (it is implied by `msg.value`), while the ERC20 token transferrer functions are not `payable` and require the explicit amount parameter. Otherwise, they include the same functions. + +## `TokenHome` + +An abstract implementation of `ITokenTransferrer` for a token transfer contract on the "home" chain with the asset to be transferred. Each `TokenHome` instance supports transferring exactly one token type (ERC20 or native) on its chain to arbitrarily many "remote" instances on other chains. It handles locking tokens to be sent to `TokenRemote` instances, as well as receiving token transfer messages to either redeem tokens it holds as collateral (i.e. unlock), or route them to other `TokenRemote` instances (i.e. "multi-hop"). In the case of a multi-hop transfer, the `TokenHome` already has the collateral locked from when the tokens were originally transferred to the first `TokenRemote` instance, so it simply updates the accounting of the transferred balances to each respective `TokenRemote` instance. Remote contracts must first be registered with a `TokenHome` instance before the home contract will allow for sending tokens to them. This is to prevent tokens from being transferred to invalid remote addresses. Anyone is able to deploy and register remote contracts, which may have been modified from this repository. It is the responsibility of the users of the home contract to independently evaluate each remote for its security and correctness. + +## `ERC20TokenHome` + +A concrete implementation of `TokenHome` and `IERC20TokenTransferrer` that handles the locking and releasing of an ERC20 token. + +## `NativeTokenHome` + +A concrete implementation of `TokenHome` and `INativeTokenTransferrer` that handles the locking and release of the native EVM asset. + +## `TokenRemote` + +An abstract implementation of `ITokenTransferrer` for a token transfer contract on a "remote" chain that receives transferred assets from a specific `TokenHome` instance. Each `TokenRemote` instance has a single `TokenHome` instance that it receives token transfers from to mint tokens. It also handles sending messages (and correspondingly burning tokens) to route tokens back to other chains (either its `TokenHome`, or other `TokenRemote` instances). Once deployed, a `TokenRemote` instance must be registered with its specified `TokenHome` contract. This is done by calling `registerWithHome` on the remote contract, which will send an ICM message to the home contract with the information to register. + +All messages sent by `TokenRemote` instances are sent to the specified `TokenHome` contract, whether they are to redeem the collateral from the `TokenHome` instance or route the tokens to another `TokenRemote` instance. Routing tokens from one `TokenRemote` instance to another is referred to as a "multi-hop", where the tokens are first sent back to their `TokenHome` contract to update its accounting, and then automatically routed on to their intended destination `TokenRemote` instance. + +TokenRemote contracts allow for scaling token amounts, which should be used when the remote asset has a higher or lower denomination than the home asset, such as allowing for a ERC20 home asset with a denomination of 6 to be used as the native EVM asset on a remote chain (with a denomination of 18). + +## `ERC20TokenRemote` + +A concrete implementation of `TokenRemote`, `IERC20TokenTransferrer`, and `IERC20` that handles the minting and burning of an ERC20 asset. Note that the `ERC20TokenRemote` contract is an ERC20 implementation itself, which is why it takes the `tokenName`, `tokenSymbol`, and `tokenDecimals` in its constructor. All of the ERC20 interface implementations are inherited from the standard OpenZeppelin ERC20 implementation, and can be overriden in other implementations if desired. + +## `NativeTokenRemote` + +A concrete implementation of `TokenRemote`, `INativeTokenTransferrer`, and `IWrappedNativeToken` that handles the minting and burning of the native EVM asset on its chain using the native minter precompile. Deployments of this contract must be given the permission to mint native coins in the chain's configuration. Note that the `NativeTokenRemote` is also an implementation of `IWrappedNativeToken` itself, which is why the `nativeAssetSymbol` must be provided in its constructor. `NativeTokenRemote` instances always have a denomination of 18, which is the denomination of the native asset of EVM chains. + +The [native minter precompile](https://build.avax.network/docs/virtual-machines/custom-precompiles#minting-native-coins) must be configured to allow the contract address of the `NativeTokenRemote` instance to call `mintNativeCoin`. The correctness of a native token transferrer implemented using `NativeTokenRemote` relies on no other accounts being allowed to call `mintNativeCoin`, which could result in the token transferrer becoming undercollateralized. Example initialization steps for a `NativeTokenRemote` instance are shown below. + +Since the native minter precompile does not provide an interface for burning the native EVM asset, the "burn" functionality is implemented by transferring the native coins to an unowned address. The contract also provides a `reportBurnedTxFees` interface in order to burn the collateral in the `TokenHome` instance that should be made unredeemable to account for native tokens burnt on the chain with the `NativeTokenRemote` instance to pay for transaction fees. + +To account for the need to bootstrap the chain using a transferred asset as its native token, the `NativeTokenRemote` takes the `initialReserveImbalance` in its constructor. Once registered with its `TokenHome`, the `TokenHome` will require the `initialReserveImbalance` to be accounted for before sending token amounts to be minted on the given remote chain. The following example demonstrates the intended initialization flow: + +1. Create a new blockchain with 100 native tokens allocated in its genesis block, and set the pre-derived `NativeTokenRemote` contract address (based on the deployer nonce) to have the permission to mint native tokens using the native minter precompile. Note that the deployer account will need to be funded in order to deploy the `NativeTokenRemote` contract, and an account used to relay messages into this chain must also be funded to relay the first messages. +2. Deploy the `NativeTokenRemote` contract to the pre-derived address set in the blockchain configuration of step 1. The `initialReserveImbalance` should be 100, matching the number of tokens allocated in the genesis block that were not initially backed by collateral in the `TokenHome` instance. +3. Call the `registerWithHome` function on the `NativeTokenRemote` instance to send an ICM message registering this remote with its `TokenHome`. This message should be relayed and delivered to the `TokenHome` instance. +4. Once registered on the `TokenHome` contract, add 100 tokens as collateral for the new `NativeTokenRemote` instance by calling the `addCollateral` function on the `TokenHome` contract. A `CollateralAdded` event will be emitted by the `TokenHome` contract with a `remaining` amount of 0 once the `NativeTokenRemote` is fully collateralized. +5. Now that the `NativeTokenRemote` contract is fully collateralized, tokens can be moved normally in both directions across the token transfer contracts by calling their `send` functions. + +The `totalNativeAssetSupply` implementation of `NativeTokenRemote` takes into account: + +- the initial reserve imbalance +- the number of native tokens that it has minted +- the number of native tokens that have been burned to pay for transaction fees +- the number of native tokens "burned" to be transferred to other chains, which are sent to a pre-defined `BURNED_FOR_TRANSFER_ADDRESS`. + +Note that the value returned by `totalNativeAssetSupply` is an upper bound on the circulating supply of the native asset on the chain using the `NativeTokenRemote` instance since tokens could be burned in other ways that it does not account for. + +## ICM Message Fees + +Fees can be optionally added to ICM messages in order to incentivize relayers to deliver them, as documented [here](https://github.com/ava-labs/icm-contracts/tree/main/contracts/teleporter#fees). The token transfer contracts in this repository allow for specifying any ERC20 token and amount to be used as the ICM message fee for single-hop transfers in either direction between `TokenHome` and `TokenRemote` instances. Fee amounts must be pre-approved to be spent by the token transfer contract before initiating a transfer. + +Multi-hop transfers between two `TokenRemote` instances involve two ICM messages: the first from the initiating `TokenRemote` instance to its home, and the second from its home to the destination `TokenRemote` instance. In the multi-hop case, the first message fee can be paid in any ERC20 token and amount (similar to the single-hop case), but the second message fee must be paid in-kind of the asset being transferred and is deducted from the amount being transferred. This restriction on the secondary message fee is necessary because the transaction on the intermediate chain routing the funds to the destination `TokenRemote` instance is not sent by the wallet performing the transfer. Because of this, it can not directly spend an arbitrary ERC20 token from that wallet. Using the asset being transferred for the optional secondary fee allows users to perform an incentivized multi-hop transfer without needing to make any interaction with the home themselves. If there is a need for the second message from the home to the destination `TokenRemote` instance to pay a fee in another asset, it is recommended to perform two single-hop transfers, which allows for specifying an arbitrary ERC20 token to be used for the fee of each. diff --git a/icm-contracts/contracts/ictt/TokenHome/ERC20TokenHome.sol b/icm-contracts/contracts/ictt/TokenHome/ERC20TokenHome.sol new file mode 100644 index 000000000..cd48a5b7d --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/ERC20TokenHome.sol @@ -0,0 +1,32 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ERC20TokenHomeUpgradeable} from "./ERC20TokenHomeUpgradeable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title ERC20TokenHome + * @notice A non-upgradeable version of {ERC20TokenHomeUpgradeable} that calls the parent upgradeable contract's initialize function. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract ERC20TokenHome is ERC20TokenHomeUpgradeable { + constructor( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion, + address tokenAddress, + uint8 tokenDecimals + ) ERC20TokenHomeUpgradeable(ICMInitializable.Allowed) { + initialize( + teleporterRegistryAddress, + teleporterManager, + minTeleporterVersion, + tokenAddress, + tokenDecimals + ); + } +} diff --git a/icm-contracts/contracts/ictt/TokenHome/ERC20TokenHomeUpgradeable.sol b/icm-contracts/contracts/ictt/TokenHome/ERC20TokenHomeUpgradeable.sol new file mode 100644 index 000000000..a04b8b513 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/ERC20TokenHomeUpgradeable.sol @@ -0,0 +1,221 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenHome} from "./TokenHome.sol"; +import {IERC20TokenHome} from "./interfaces/IERC20TokenHome.sol"; +import {IERC20SendAndCallReceiver} from "../interfaces/IERC20SendAndCallReceiver.sol"; +import { + SendTokensInput, + SendAndCallInput, + SingleHopCallMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/ERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {CallUtils} from "@utilities/CallUtils.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title ERC20TokenHomeUpgradeable + * @notice An {IERC20TokenHome} implementation that locks a specified ERC20 token to be sent to + * TokenRemote instances on other chains. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract ERC20TokenHomeUpgradeable is IERC20TokenHome, TokenHome { + using SafeERC20 for IERC20; + + // solhint-disable private-vars-leading-underscore + /** + * @dev Namespace storage slots following the ERC-7201 standard to prevent + * storage collisions between upgradeable contracts. + * + * @custom:storage-location erc7201:avalanche-ictt.storage.ERC20TokenHome + */ + struct ERC20TokenHomeStorage { + /// @notice The ERC20 token this home contract transfers to TokenRemote instances. + IERC20 _token; + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Storage slot computed based off ERC-7201 formula + * keccak256(abi.encode(uint256(keccak256("avalanche-ictt.storage.ERC20TokenHome")) - 1)) & ~bytes32(uint256(0xff)); + */ + bytes32 public constant ERC20_TOKEN_HOME_STORAGE_LOCATION = + 0x914a9547f6c3ddce1d5efbd9e687708f0d1d408ce129e8e1a88bce4f40e29500; + + // solhint-disable ordering + function _getERC20TokenHomeStorage() private pure returns (ERC20TokenHomeStorage storage $) { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := ERC20_TOKEN_HOME_STORAGE_LOCATION + } + } + + constructor( + ICMInitializable init + ) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initializes the token TokenHome instance to send ERC20 tokens to TokenRemote instances on other chains. + * @param teleporterRegistryAddress The current blockchain ID's Teleporter registry + * address. See here for details: https://github.com/ava-labs/icm-contracts/tree/main/contracts/teleporter/registry + * @param teleporterManager Address that manages this contract's integration with the + * Teleporter registry and Teleporter versions. + * @param minTeleporterVersion Minimum Teleporter version supported by this contract. + * @param tokenAddress The ERC20 token contract address to be transferred by the home. + * @param tokenDecimals The number of decimals for the ERC20 token + */ + function initialize( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion, + address tokenAddress, + uint8 tokenDecimals + ) public initializer { + __ERC20TokenHome_init( + teleporterRegistryAddress, + teleporterManager, + minTeleporterVersion, + tokenAddress, + tokenDecimals + ); + } + + // solhint-disable-next-line func-name-mixedcase + function __ERC20TokenHome_init( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion, + address tokenAddress, + uint8 tokenDecimals + ) internal onlyInitializing { + __TokenHome_init( + teleporterRegistryAddress, + teleporterManager, + minTeleporterVersion, + tokenAddress, + tokenDecimals + ); + __ERC20TokenHome_init_unchained(tokenAddress); + } + + // solhint-disable-next-line func-name-mixedcase + function __ERC20TokenHome_init_unchained( + address tokenAddress + ) internal onlyInitializing { + _getERC20TokenHomeStorage()._token = IERC20(tokenAddress); + } + // solhint-enable ordering + + /** + * @dev See {IERC20TokenTransferrer-send} + */ + function send(SendTokensInput calldata input, uint256 amount) external { + _send(input, amount); + } + + /** + * @dev See {IERC20TokenTransferrer-sendAndCall} + */ + function sendAndCall(SendAndCallInput calldata input, uint256 amount) external { + _sendAndCall({ + sourceBlockchainID: getBlockchainID(), + originTokenTransferrerAddress: address(this), + originSenderAddress: _msgSender(), + input: input, + amount: amount + }); + } + + /** + * @dev See {IERC20TokenHome-addCollateral} + */ + function addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) external { + _addCollateral(remoteBlockchainID, remoteTokenTransferrerAddress, amount); + } + + /** + * @dev See {TokenHome-_deposit} + */ + function _deposit( + uint256 amount + ) internal virtual override returns (uint256) { + ERC20TokenHomeStorage storage $ = _getERC20TokenHomeStorage(); + return SafeERC20TransferFrom.safeTransferFrom($._token, _msgSender(), amount); + } + + /** + * @dev See {TokenHome-_withdraw} + */ + function _withdraw(address recipient, uint256 amount) internal virtual override { + ERC20TokenHomeStorage storage $ = _getERC20TokenHomeStorage(); + emit TokensWithdrawn(recipient, amount); + $._token.safeTransfer(recipient, amount); + } + + /** + * @dev See {TokenHome-_handleSendAndCall} + * + * Approves the recipient contract to spend the amount of tokens from this contract, + * and calls {IERC20SendAndCallReceiver-receiveTokens} on the recipient contract. + * If the call fails or doesn't spend all of the tokens, the remaining amount is + * sent to the fallback recipient. + */ + function _handleSendAndCall( + SingleHopCallMessage memory message, + uint256 amount + ) internal virtual override { + ERC20TokenHomeStorage storage $ = _getERC20TokenHomeStorage(); + IERC20 token = $._token; + // Approve the recipient contract to spend the amount from the collateral. + SafeERC20.safeIncreaseAllowance($._token, message.recipientContract, amount); + + // Encode the call to {IERC20SendAndCallReceiver-receiveTokens} + bytes memory payload = abi.encodeCall( + IERC20SendAndCallReceiver.receiveTokens, + ( + message.sourceBlockchainID, + message.originTokenTransferrerAddress, + message.originSenderAddress, + address(token), + amount, + message.recipientPayload + ) + ); + + // Call the recipient contract with the given payload and gas amount. + bool success = CallUtils._callWithExactGas( + message.recipientGasLimit, message.recipientContract, payload + ); + + uint256 remainingAllowance = token.allowance(address(this), message.recipientContract); + + // Reset the recipient contract allowance to 0. + SafeERC20.forceApprove(token, message.recipientContract, 0); + + if (success) { + emit CallSucceeded(message.recipientContract, amount); + } else { + emit CallFailed(message.recipientContract, amount); + } + + // Transfer any remaining allowance to the fallback recipient. This will be the + // full amount if the call failed. + if (remainingAllowance > 0) { + token.safeTransfer(message.fallbackRecipient, remainingAllowance); + } + } +} diff --git a/icm-contracts/contracts/ictt/TokenHome/NativeTokenHome.sol b/icm-contracts/contracts/ictt/TokenHome/NativeTokenHome.sol new file mode 100644 index 000000000..cd2cf58d6 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/NativeTokenHome.sol @@ -0,0 +1,27 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {NativeTokenHomeUpgradeable} from "./NativeTokenHomeUpgradeable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title NativeTokenHome + * @notice A non-upgradeable version of {NativeTokenHomeUpgradeable} that calls the parent upgradeable contract's initialize function. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract NativeTokenHome is NativeTokenHomeUpgradeable { + constructor( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion, + address wrappedTokenAddress + ) NativeTokenHomeUpgradeable(ICMInitializable.Allowed) { + initialize( + teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress + ); + } +} diff --git a/icm-contracts/contracts/ictt/TokenHome/NativeTokenHomeUpgradeable.sol b/icm-contracts/contracts/ictt/TokenHome/NativeTokenHomeUpgradeable.sol new file mode 100644 index 000000000..d821ed4ed --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/NativeTokenHomeUpgradeable.sol @@ -0,0 +1,227 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenHome} from "./TokenHome.sol"; +import {INativeTokenHome} from "./interfaces/INativeTokenHome.sol"; +import {INativeSendAndCallReceiver} from "../interfaces/INativeSendAndCallReceiver.sol"; +import { + SendTokensInput, + SendAndCallInput, + SingleHopCallMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {IWrappedNativeToken} from "../interfaces/IWrappedNativeToken.sol"; +import {CallUtils} from "@utilities/CallUtils.sol"; +import {SafeWrappedNativeTokenDeposit} from "@utilities/SafeWrappedNativeTokenDeposit.sol"; +import {Address} from "@openzeppelin/contracts@5.0.2/utils/Address.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title NativeTokenHomeUpgradeable + * @notice An {INativeTokenHome} implementation that locks the native token of this chain to be transferred to + * TokenRemote instances on other chains. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract NativeTokenHomeUpgradeable is INativeTokenHome, TokenHome { + using Address for address payable; + + // solhint-disable private-vars-leading-underscore + /** + * @dev Namespace storage slots following the ERC-7201 standard to prevent + * storage collisions between upgradeable contracts. + * + * @custom:storage-location erc7201:avalanche-ictt.storage.NativeTokenHome + */ + struct NativeTokenHomeStorage { + /** + * @notice The wrapped native token contract that represents the native tokens on this chain. + */ + IWrappedNativeToken _wrappedToken; + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Storage slot computed based off ERC-7201 formula + * keccak256(abi.encode(uint256(keccak256("avalanche-ictt.storage.NativeTokenHome")) - 1)) & ~bytes32(uint256(0xff)); + */ + bytes32 public constant NATIVE_TOKEN_HOME_STORAGE_LOCATION = + 0x3b5030f10c94fcbdaa3022348ff0b82dbd4c0c71339e41ff59d0bdc92179d600; + + // solhint-disable ordering + function _getNativeTokenHomeStorage() private pure returns (NativeTokenHomeStorage storage $) { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := NATIVE_TOKEN_HOME_STORAGE_LOCATION + } + } + + constructor( + ICMInitializable init + ) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initializes this token TokenHome instance to send native tokens to TokenRemote instances on other chains. + * Always uses a {tokenDecimals} value of 18 since it is the denomination of the native token of EVM instances. + * @param teleporterRegistryAddress The current blockchain ID's Teleporter registry + * address. See here for details: https://github.com/ava-labs/icm-contracts/tree/main/contracts/teleporter/registry + * @param teleporterManager Address that manages this contract's integration with the + * Teleporter registry and Teleporter versions. + * @param minTeleporterVersion Minimum Teleporter version supported by this contract. + * @param wrappedTokenAddress The wrapped native token contract address of the native asset + * to be transferred to TokenRemote instances. + */ + function initialize( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion, + address wrappedTokenAddress + ) public initializer { + __NativeTokenHome_init( + teleporterRegistryAddress, teleporterManager, minTeleporterVersion, wrappedTokenAddress + ); + } + + // solhint-disable-next-line func-name-mixedcase + function __NativeTokenHome_init( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion, + address wrappedTokenAddress + ) internal onlyInitializing { + __TokenHome_init( + teleporterRegistryAddress, + teleporterManager, + minTeleporterVersion, + wrappedTokenAddress, + 18 + ); + __NativeTokenHome_init_unchained(wrappedTokenAddress); + } + + // solhint-disable-next-line func-name-mixedcase + function __NativeTokenHome_init_unchained( + address wrappedTokenAddress + ) internal onlyInitializing { + _getNativeTokenHomeStorage()._wrappedToken = IWrappedNativeToken(wrappedTokenAddress); + } + // solhint-enable ordering + + /** + * @notice Receives native tokens transferred to this contract. + * @dev This function is called when the token transferrer is withdrawing native tokens to + * transfer to the recipient. The caller must be the wrapped native token contract. + */ + receive() external payable { + // The caller here is expected to be {tokenAddress} directly, and not through a meta-transaction, + // so we check for `msg.sender` instead of `_msgSender()`. + require( + msg.sender == address(_getNativeTokenHomeStorage()._wrappedToken), + "NativeTokenHome: invalid receive payable sender" + ); + } + + /** + * @dev See {INativeTokenTransferrer-send} + */ + function send( + SendTokensInput calldata input + ) external payable { + _send(input, msg.value); + } + + /** + * @dev See {INativeTokenTransferrer-sendAndCall} + */ + function sendAndCall( + SendAndCallInput calldata input + ) external payable { + _sendAndCall({ + sourceBlockchainID: getBlockchainID(), + originTokenTransferrerAddress: address(this), + originSenderAddress: _msgSender(), + input: input, + amount: msg.value + }); + } + + /** + * @dev See {INativeTokenHome-addCollateral} + */ + function addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress + ) external payable { + _addCollateral(remoteBlockchainID, remoteTokenTransferrerAddress, msg.value); + } + + /** + * @dev See {TokenHome-_deposit} + * Deposits the native tokens sent to this contract + */ + function _deposit( + uint256 amount + ) internal virtual override returns (uint256) { + NativeTokenHomeStorage storage $ = _getNativeTokenHomeStorage(); + return SafeWrappedNativeTokenDeposit.safeDeposit($._wrappedToken, amount); + } + + /** + * @dev See {TokenHome-_withdraw} + * Withdraws the wrapped tokens for native tokens, + * and sends them to the recipient. + */ + function _withdraw(address recipient, uint256 amount) internal virtual override { + NativeTokenHomeStorage storage $ = _getNativeTokenHomeStorage(); + emit TokensWithdrawn(recipient, amount); + $._wrappedToken.withdraw(amount); + payable(recipient).sendValue(amount); + } + + /** + * @dev See {TokenHome-_handleSendAndCall} + * + * Send the native tokens to the recipient contract as a part of the call to + * {INativeSendAndCallReceiver-receiveTokens} on the recipient contract. + * If the call fails or doesn't spend all of the tokens, the remaining amount is + * sent to the fallback recipient. + */ + function _handleSendAndCall( + SingleHopCallMessage memory message, + uint256 amount + ) internal virtual override { + NativeTokenHomeStorage storage $ = _getNativeTokenHomeStorage(); + // Withdraw the native token from the wrapped native token contract. + $._wrappedToken.withdraw(amount); + + // Encode the call to {INativeSendAndCallReceiver-receiveTokens} + bytes memory payload = abi.encodeCall( + INativeSendAndCallReceiver.receiveTokens, + ( + message.sourceBlockchainID, + message.originTokenTransferrerAddress, + message.originSenderAddress, + message.recipientPayload + ) + ); + + // Call the recipient contract with the given payload, gas amount, and value. + bool success = CallUtils._callWithExactGasAndValue( + message.recipientGasLimit, amount, message.recipientContract, payload + ); + + // If the call failed, send the funds to the fallback recipient. + if (success) { + emit CallSucceeded(message.recipientContract, amount); + } else { + emit CallFailed(message.recipientContract, amount); + payable(message.fallbackRecipient).sendValue(amount); + } + } +} diff --git a/icm-contracts/contracts/ictt/TokenHome/TokenHome.sol b/icm-contracts/contracts/ictt/TokenHome/TokenHome.sol new file mode 100644 index 000000000..2c9df7157 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/TokenHome.sol @@ -0,0 +1,823 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterMessageInput, TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; +import {TeleporterRegistryOwnableAppUpgradeable} from + "@teleporter/registry/TeleporterRegistryOwnableAppUpgradeable.sol"; +import {ITokenHome, RemoteTokenTransferrerSettings} from "./interfaces/ITokenHome.sol"; +import { + SendTokensInput, + SendAndCallInput, + TransferrerMessageType, + TransferrerMessage, + SingleHopSendMessage, + SingleHopCallMessage, + MultiHopSendMessage, + MultiHopCallMessage, + RegisterRemoteMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {SendReentrancyGuardUpgradeable} from "@utilities/SendReentrancyGuardUpgradeable.sol"; +import {TokenScalingUtils} from "@utilities/TokenScalingUtils.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {IWarpMessenger} from "@subnet-evm/IWarpMessenger.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/ERC20.sol"; + +/** + * @title TokenHome + * @dev Abstract contract for a token transferrer home that sends its specified token to {TokenRemote} instances. + * + * This contract also handles multi-hop transfers, where tokens sent from a {TokenRemote} + * instance are forwarded to another {TokenRemote} instance. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract TokenHome is + ITokenHome, + TeleporterRegistryOwnableAppUpgradeable, + SendReentrancyGuardUpgradeable +{ + // solhint-disable private-vars-leading-underscore + /** + * @dev Namespace storage slots following the ERC-7201 standard to prevent + * storage collisions between upgradeable contracts. + * + * @custom:storage-location erc7201:avalanche-ictt.storage.TokenHome + */ + struct TokenHomeStorage { + /// @notice The blockchain ID of the chain this contract is deployed on. + bytes32 _blockchainID; + /** + * @notice The token address this home contract transfers to TokenRemote instances. + * For multi-hop transfers, this {tokenAddress} is always used to pay for the secondary message fees. + * If the token is an ERC20 token, the contract address is directly passed in. + * If the token is a native asset, the contract address is the wrapped token contract. + */ + address _tokenAddress; + uint8 _tokenDecimals; + /** + * @notice Tracks the settings for each remote token transferrer instance. TokenRemote instances + * must register with their {TokenHome} contracts via Teleporter message to be able to + * receive tokens from this contract. + */ + mapping( + bytes32 remoteBlockchainID + => mapping( + address remoteTokenTransferrerAddress + => RemoteTokenTransferrerSettings remoteSettings + ) + ) _registeredRemotes; + /** + * @notice Tracks the balances of tokens sent to TokenRemote instances. + * Balances are represented in the remote token's denomination, + * and token transferrers are not allowed to unwrap more than has been sent to them. + * @dev (remoteBlockchainID, remoteTokenTransferrerAddress) -> balance + */ + mapping( + bytes32 remoteBlockchainID + => mapping(address remoteTokenTransferrerAddress => uint256 balance) + ) _transferredBalances; + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Storage slot computed based off ERC-7201 formula + * keccak256(abi.encode(uint256(keccak256("avalanche-ictt.storage.TokenHome")) - 1)) & ~bytes32(uint256(0xff)); + */ + bytes32 public constant TOKEN_HOME_STORAGE_LOCATION = + 0x9316912b5a9db88acbe872c934fdd0a46c436c6dcba332d649c4d57c7bc9e600; + + // solhint-disable ordering + function _getTokenHomeStorage() private pure returns (TokenHomeStorage storage $) { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := TOKEN_HOME_STORAGE_LOCATION + } + } + + /** + * @notice Initializes this home token transferrer instance to send tokens to TokenRemote instances on other chains. + * @param teleporterRegistryAddress The address of the TeleporterRegistry contract. + * @param teleporterManager Address that manages this contract's integration with the + * Teleporter registry and Teleporter versions. + * @param minTeleporterVersion Minimum Teleporter version supported by this contract. + * @param tokenAddress The token contract address to be transferredd by the home instance. + * @param tokenDecimals The number of decimals for the token being transferred. + */ + // solhint-disable-next-line func-name-mixedcase + function __TokenHome_init( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion, + address tokenAddress, + uint8 tokenDecimals + ) internal virtual onlyInitializing { + __TeleporterRegistryOwnableApp_init( + teleporterRegistryAddress, teleporterManager, minTeleporterVersion + ); + __SendReentrancyGuard_init(); + __TokenHome_init_unchained(tokenAddress, tokenDecimals); + } + + // solhint-disable-next-line func-name-mixedcase + function __TokenHome_init_unchained( + address tokenAddress, + uint8 tokenDecimals + ) internal onlyInitializing { + require(tokenAddress != address(0), "TokenHome: zero token address"); + require( + tokenDecimals <= TokenScalingUtils.MAX_TOKEN_DECIMALS, + "TokenHome: token decimals too high" + ); + TokenHomeStorage storage $ = _getTokenHomeStorage(); + $._blockchainID = + IWarpMessenger(0x0200000000000000000000000000000000000005).getBlockchainID(); + $._tokenAddress = tokenAddress; + $._tokenDecimals = tokenDecimals; + } + // solhint-enable ordering + + function getRemoteTokenTransferrerSettings( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress + ) public view returns (RemoteTokenTransferrerSettings memory) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + return $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress]; + } + + function getTransferredBalance( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress + ) public view returns (uint256) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + return $._transferredBalances[remoteBlockchainID][remoteTokenTransferrerAddress]; + } + + function getTokenAddress() public view returns (address) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + return $._tokenAddress; + } + + function getBlockchainID() public view returns (bytes32) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + return $._blockchainID; + } + + function _registerRemote( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + RegisterRemoteMessage memory message + ) internal { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + require(remoteBlockchainID != bytes32(0), "TokenHome: zero remote blockchain ID"); + require( + remoteBlockchainID != $._blockchainID, "TokenHome: cannot register remote on same chain" + ); + require( + remoteTokenTransferrerAddress != address(0), + "TokenHome: zero remote token transferrer address" + ); + require( + !$._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress].registered, + "TokenHome: remote already registered" + ); + require( + message.remoteTokenDecimals <= TokenScalingUtils.MAX_TOKEN_DECIMALS, + "TokenHome: remote token decimals too high" + ); + require( + message.homeTokenDecimals == $._tokenDecimals, "TokenHome: invalid home token decimals" + ); + + (uint256 tokenMultiplier, bool multiplyOnRemote) = TokenScalingUtils + .deriveTokenMultiplierValues($._tokenDecimals, message.remoteTokenDecimals); + + // Calculate the collateral needed in home token denomination. + uint256 collateralNeeded = TokenScalingUtils.removeTokenScale( + tokenMultiplier, multiplyOnRemote, message.initialReserveImbalance + ); + + // Round up the collateral needed by 1 in the case that {multiplyOnRemote} is true and + // {initialReserveImbalance} is not divisible by the {tokenMultiplier} to + // ensure that the full amount is accounted for. + if (multiplyOnRemote && message.initialReserveImbalance % tokenMultiplier != 0) { + collateralNeeded += 1; + } + + $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress] = + RemoteTokenTransferrerSettings({ + registered: true, + collateralNeeded: collateralNeeded, + tokenMultiplier: tokenMultiplier, + multiplyOnRemote: multiplyOnRemote + }); + + emit RemoteRegistered( + remoteBlockchainID, + remoteTokenTransferrerAddress, + collateralNeeded, + message.remoteTokenDecimals + ); + } + + /** + * @notice Sends tokens to the specified remote token transferrer instance. + * + * @dev Increases the balance sent to the remote token transferrer instance, + * and uses Teleporter to send a cross chain message. The amount passed is assumed to + * be already scaled to the local denomination for this token home. + * Requirements: + * + * - The TokenRemote instance specified by {input.destinationBlockchainID} and {input.destinationTokenTransferrerAddress} must + * be registered with this contract. + * - {input.recipient} cannot be the zero address + * - {amount} must be greater than 0 + */ + function _send(SendTokensInput memory input, uint256 amount) internal sendNonReentrant { + _validateSendTokensInput(input); + // Require that a single hop transfer does not have a multi-hop fallback recipient. + require(input.multiHopFallback == address(0), "TokenHome: non-zero multi-hop fallback"); + + (uint256 adjustedAmount, uint256 feeAmount) = _prepareSend({ + remoteBlockchainID: input.destinationBlockchainID, + remoteTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + amount: amount, + primaryFeeTokenAddress: input.primaryFeeTokenAddress, + feeAmount: input.primaryFee + }); + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_SEND, + payload: abi.encode( + SingleHopSendMessage({recipient: input.recipient, amount: adjustedAmount}) + ) + }); + + // Send message to the TokenRemote instance + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: feeAmount + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensSent(messageID, _msgSender(), input, adjustedAmount); + } + + /** + * @notice Routes tokens from a multi-hop message to the specified remote token transferrer instance. + * + * @dev Increases the balance sent to the remote token transferrer instance, + * and uses Teleporter to send a cross chain message. The amount passed is assumed to + * be already scaled to the local denomination for this token home. + * Requirements: + * + * - The TokenRemote instance specified by {input.destinationBlockchainID} and {input.destinationTokenTransferrerAddress} must + * be registered with this contract. + * - {input.recipient} cannot be the zero address + * - {amount} must be greater than 0 + */ + function _routeMultiHop( + SendTokensInput memory input, + uint256 amount + ) internal sendNonReentrant { + _validateSendTokensInput(input); + + uint256 adjustedAmount = _prepareMultiHopRouting( + input.destinationBlockchainID, + input.destinationTokenTransferrerAddress, + amount, + input.primaryFee + ); + + if (adjustedAmount == 0) { + // If the adjusted amount is zero for any reason (i.e. unregistered remote, + // being scaled down to zero, etc.), send the tokens to the multi-hop fallback. + _withdraw(input.multiHopFallback, amount); + return; + } + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_SEND, + payload: abi.encode( + SingleHopSendMessage({recipient: input.recipient, amount: adjustedAmount}) + ) + }); + + // Send message to the TokenRemote instance. + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: input.primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensRouted(messageID, input, adjustedAmount); + } + + function _sendAndCall( + bytes32 sourceBlockchainID, + address originTokenTransferrerAddress, + address originSenderAddress, + SendAndCallInput memory input, + uint256 amount + ) internal sendNonReentrant { + _validateSendAndCallInput(input); + + // Require that a single hop transfer does not have a multi-hop fallback recipient. + require(input.multiHopFallback == address(0), "TokenHome: non-zero multi-hop fallback"); + + (uint256 adjustedAmount, uint256 feeAmount) = _prepareSend({ + remoteBlockchainID: input.destinationBlockchainID, + remoteTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + amount: amount, + primaryFeeTokenAddress: input.primaryFeeTokenAddress, + feeAmount: input.primaryFee + }); + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_CALL, + payload: abi.encode( + SingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originTokenTransferrerAddress: originTokenTransferrerAddress, + originSenderAddress: originSenderAddress, + recipientContract: input.recipientContract, + amount: adjustedAmount, + recipientPayload: input.recipientPayload, + recipientGasLimit: input.recipientGasLimit, + fallbackRecipient: input.fallbackRecipient + }) + ) + }); + + // Send message to the TokenRemote instance. + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: feeAmount + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensAndCallSent(messageID, originSenderAddress, input, adjustedAmount); + } + + function _routeMultiHopSendAndCall( + bytes32 sourceBlockchainID, + address originTokenTransferrerAddress, + address originSenderAddress, + SendAndCallInput memory input, + uint256 amount + ) internal sendNonReentrant { + _validateSendAndCallInput(input); + uint256 adjustedAmount = _prepareMultiHopRouting( + input.destinationBlockchainID, + input.destinationTokenTransferrerAddress, + amount, + input.primaryFee + ); + + if (adjustedAmount == 0) { + // If the adjusted amount is zero for any reason (i.e. unregistered remote, + // being scaled down to zero, etc.), send the tokens to the multi-hop fallback recipient. + _withdraw(input.multiHopFallback, amount); + return; + } + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_CALL, + payload: abi.encode( + SingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originTokenTransferrerAddress: originTokenTransferrerAddress, + originSenderAddress: originSenderAddress, + recipientContract: input.recipientContract, + amount: adjustedAmount, + recipientPayload: input.recipientPayload, + recipientGasLimit: input.recipientGasLimit, + fallbackRecipient: input.fallbackRecipient + }) + ) + }); + + // Send message to the TokenRemote instance. + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: input.primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensAndCallRouted(messageID, input, adjustedAmount); + } + + /** + * @dev See {INativeTokenHome-addCollateral} + */ + function _addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) internal sendNonReentrant { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + RemoteTokenTransferrerSettings memory remoteSettings = + $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress]; + require(remoteSettings.registered, "TokenHome: remote not registered"); + require(remoteSettings.collateralNeeded > 0, "TokenHome: zero collateral needed"); + + // Deposit the full amount, and withdraw back to the sender if there is excess. + amount = _deposit(amount); + + // Calculate the remaining collateral needed, any excess amount, and adjust + // {amount} to represent the amount of tokens added as collateral. + uint256 remainingCollateralNeeded; + uint256 excessAmount; + if (amount >= remoteSettings.collateralNeeded) { + remainingCollateralNeeded = 0; + excessAmount = amount - remoteSettings.collateralNeeded; + amount = remoteSettings.collateralNeeded; + } else { + remainingCollateralNeeded = remoteSettings.collateralNeeded - amount; + } + + // Update the remaining collateral needed. + $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress].collateralNeeded = + remainingCollateralNeeded; + emit CollateralAdded( + remoteBlockchainID, remoteTokenTransferrerAddress, amount, remainingCollateralNeeded + ); + + // If there is excess amount, send it back to the sender. + if (excessAmount > 0) { + _withdraw(_msgSender(), excessAmount); + } + } + + /** + * @dev See {ITeleporterUpgradeable-_receiveTeleporterMessage} + * + * Handles the processing of Teleporter messages sent to this contract. + * Supported message types include registering a TokenRemote instance, single-hop sends, + * single-hop calls, multi-hop sends, and multi-hop calls. + */ + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message + ) internal override { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + TransferrerMessage memory transferrerMessage = abi.decode(message, (TransferrerMessage)); + if (transferrerMessage.messageType == TransferrerMessageType.SINGLE_HOP_SEND) { + SingleHopSendMessage memory payload = + abi.decode(transferrerMessage.payload, (SingleHopSendMessage)); + + uint256 homeAmount = + _processSingleHopTransfer(sourceBlockchainID, originSenderAddress, payload.amount); + + // Send the tokens to the recipient. + _withdraw(payload.recipient, homeAmount); + return; + } else if (transferrerMessage.messageType == TransferrerMessageType.SINGLE_HOP_CALL) { + SingleHopCallMessage memory payload = + abi.decode(transferrerMessage.payload, (SingleHopCallMessage)); + + uint256 homeAmount = + _processSingleHopTransfer(sourceBlockchainID, originSenderAddress, payload.amount); + + // Verify that the payload's source blockchain ID and origin token transferrer address matches the source blockchain ID + // and origin sender address passed from Teleporter. + require( + payload.sourceBlockchainID == sourceBlockchainID, + "TokenHome: mismatched source blockchain ID" + ); + require( + payload.originTokenTransferrerAddress == originSenderAddress, + "TokenHome: mismatched origin sender address" + ); + + _handleSendAndCall(payload, homeAmount); + return; + } else if (transferrerMessage.messageType == TransferrerMessageType.MULTI_HOP_SEND) { + MultiHopSendMessage memory payload = + abi.decode(transferrerMessage.payload, (MultiHopSendMessage)); + + (uint256 homeAmount, uint256 fee) = _processMultiHopTransfer( + sourceBlockchainID, originSenderAddress, payload.amount, payload.secondaryFee + ); + + // For a multi-hop send, the fee token address has to be {tokenAddress}, + // because the fee is taken from the amount that has already been deposited. + // For ERC20 tokens, the token address of the contract is directly passed. + // For native assets, the contract address is the wrapped token contract. + _routeMultiHop( + SendTokensInput({ + destinationBlockchainID: payload.destinationBlockchainID, + destinationTokenTransferrerAddress: payload.destinationTokenTransferrerAddress, + recipient: payload.recipient, + primaryFeeTokenAddress: $._tokenAddress, + primaryFee: fee, + secondaryFee: 0, + requiredGasLimit: payload.secondaryGasLimit, + multiHopFallback: payload.multiHopFallback + }), + homeAmount + ); + return; + } else if (transferrerMessage.messageType == TransferrerMessageType.MULTI_HOP_CALL) { + MultiHopCallMessage memory payload = + abi.decode(transferrerMessage.payload, (MultiHopCallMessage)); + + (uint256 homeAmount, uint256 fee) = _processMultiHopTransfer( + sourceBlockchainID, originSenderAddress, payload.amount, payload.secondaryFee + ); + + // For a multi-hop send, the fee token address has to be {tokenAddress}, + // because the fee is taken from the amount that has already been deposited. + // For ERC20 tokens, the token address of the contract is directly passed. + // For native assets, the contract address is the wrapped token contract. + _routeMultiHopSendAndCall({ + sourceBlockchainID: sourceBlockchainID, + originTokenTransferrerAddress: originSenderAddress, + originSenderAddress: payload.originSenderAddress, + input: SendAndCallInput({ + destinationBlockchainID: payload.destinationBlockchainID, + destinationTokenTransferrerAddress: payload.destinationTokenTransferrerAddress, + recipientContract: payload.recipientContract, + recipientPayload: payload.recipientPayload, + requiredGasLimit: payload.secondaryRequiredGasLimit, + recipientGasLimit: payload.recipientGasLimit, + multiHopFallback: payload.multiHopFallback, + fallbackRecipient: payload.fallbackRecipient, + primaryFeeTokenAddress: $._tokenAddress, + primaryFee: fee, + secondaryFee: 0 + }), + amount: homeAmount + }); + return; + } else if (transferrerMessage.messageType == TransferrerMessageType.REGISTER_REMOTE) { + RegisterRemoteMessage memory payload = + abi.decode(transferrerMessage.payload, (RegisterRemoteMessage)); + _registerRemote(sourceBlockchainID, originSenderAddress, payload); + } + } + + /** + * @notice Deposits tokens from the sender to this contract, + * and returns the adjusted amount of tokens deposited. + * @param amount The initial amount sent to this contract. + * @return The actual amount deposited to this contract. + */ + function _deposit( + uint256 amount + ) internal virtual returns (uint256); + + /** + * @notice Withdraws tokens to the recipient address. + * @param recipient The address to withdraw tokens to + * @param amount The amount of tokens to withdraw + */ + function _withdraw(address recipient, uint256 amount) internal virtual; + + /** + * @notice Processes a send and call message by calling the recipient contract. + * @param message The send and call message include recipient calldata + * @param amount The amount of tokens to be sent to the recipient. This amount is assumed to be + * already scaled to the local denomination for this token home. + */ + function _handleSendAndCall( + SingleHopCallMessage memory message, + uint256 amount + ) internal virtual; + + /** + * @notice Processes a received single hop transfer from a TokenRemote instance. + * Validates that the message is sent from a registered TokenRemote instance, + * and is already collateralized. + * @param remoteBlockchainID The blockchain ID of the TokenRemote instance. + * @param remoteTokenTransferrerAddress The address of the TokenRemote instance. + * @param amount The amount of tokens sent back from remote, denominated by the + * remote's token scale amount. + */ + function _processSingleHopTransfer( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) private returns (uint256) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + RemoteTokenTransferrerSettings memory remoteSettings = + $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress]; + + return _processReceivedTransfer( + remoteSettings, remoteBlockchainID, remoteTokenTransferrerAddress, amount + ); + } + + /** + * @notice Processes a received multi-hop transfer from a TokenRemote instance. + * Validates that the message is sent from a registered TokenRemote instance, + * and is already collateralized. + * @param remoteBlockchainID The blockchain ID of the TokenRemote instance. + * @param remoteTokenTransferrerAddress The address of the TokenRemote instance. + * @param amount The amount of tokens sent back from remote, denominated by the + * remote's token scale amount. + * @param secondaryFee The Teleporter fee for the second hop of the mutihop transfer + */ + function _processMultiHopTransfer( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount, + uint256 secondaryFee + ) private returns (uint256, uint256) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + RemoteTokenTransferrerSettings memory remoteSettings = + $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress]; + + uint256 transferAmount = _processReceivedTransfer( + remoteSettings, remoteBlockchainID, remoteTokenTransferrerAddress, amount + ); + + uint256 fee = TokenScalingUtils.removeTokenScale( + remoteSettings.tokenMultiplier, remoteSettings.multiplyOnRemote, secondaryFee + ); + + return (transferAmount, fee); + } + + /** + * @notice Processes a received transfer from a TokenRemote instance. + * Deducts the balance transferred to the given TokenRemote instance. + * Removes the token scaling of the remote, checks the associated home token + * amount is greater than zero, and returns the home token amount. + * @param remoteSettings The token transferrer settings for the TokenRemote instance we received the transfer from. + * @param remoteBlockchainID The blockchain ID of the TokenRemote instance. + * @param remoteTokenTransferrerAddress The address of the TokenRemote instance. + * @param amount The amount of tokens sent back from remote, denominated by the + * remote's token scale amount. + */ + function _processReceivedTransfer( + RemoteTokenTransferrerSettings memory remoteSettings, + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) private returns (uint256) { + // Require that the remote is registered and has no collateral needed. + require(remoteSettings.registered, "TokenHome: remote not registered"); + require(remoteSettings.collateralNeeded == 0, "TokenHome: remote not collateralized"); + + // Deduct the balance transferred to the given TokenRemote instance prior to scaling the amount. + _deductSenderBalance(remoteBlockchainID, remoteTokenTransferrerAddress, amount); + + // Remove the token scaling of the remote and get home token amount. + uint256 homeAmount = TokenScalingUtils.removeTokenScale( + remoteSettings.tokenMultiplier, remoteSettings.multiplyOnRemote, amount + ); + + // Require that the home token amount is greater than zero after removed scaling. + require(homeAmount > 0, "TokenHome: zero token amount"); + return homeAmount; + } + + /** + * @notice Prepares a multi-hop send by checking the TokenRemote instance settings + * and adjusting the amount to be sent. + * @return The scaled amount to be sent to the TokenRemote instance. Zero can be returned if the + * TokenRemote instance is not registered, needs collateral, or the scaled amount is zero. + */ + function _prepareMultiHopRouting( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount, + uint256 fee + ) private returns (uint256) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + RemoteTokenTransferrerSettings memory remoteSettings = + $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress]; + if (!remoteSettings.registered || remoteSettings.collateralNeeded > 0) { + return 0; + } + + // Subtract fee amount from amount prior to scaling. + require(amount > fee, "TokenHome: insufficient amount to cover fees"); + amount -= fee; + + // Scale the amount based on the token multiplier for the given TokenRemote instance. + uint256 scaledAmount = TokenScalingUtils.applyTokenScale( + remoteSettings.tokenMultiplier, remoteSettings.multiplyOnRemote, amount + ); + if (scaledAmount == 0) { + return 0; + } + + // Increase the balance of the TokenRemote instance by the scaled amount. + $._transferredBalances[remoteBlockchainID][remoteTokenTransferrerAddress] += scaledAmount; + + return scaledAmount; + } + + /** + * @dev Prepares tokens to be sent to another chain by handling the + * locking of the token amount in this contract and updating the accounting + * balances. + */ + function _prepareSend( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount, + address primaryFeeTokenAddress, + uint256 feeAmount + ) private returns (uint256, uint256) { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + RemoteTokenTransferrerSettings memory remoteSettings = + $._registeredRemotes[remoteBlockchainID][remoteTokenTransferrerAddress]; + require(remoteSettings.registered, "TokenHome: remote not registered"); + require(remoteSettings.collateralNeeded == 0, "TokenHome: collateral needed for remote"); + + // Deposit the funds sent from the user to the token transferrer, + // and set to adjusted amount after deposit. + amount = _deposit(amount); + + if (feeAmount > 0) { + feeAmount = SafeERC20TransferFrom.safeTransferFrom( + IERC20(primaryFeeTokenAddress), _msgSender(), feeAmount + ); + } + + // Scale the amount based on the token multiplier for the given TokenRemote instance. + uint256 scaledAmount = TokenScalingUtils.applyTokenScale( + remoteSettings.tokenMultiplier, remoteSettings.multiplyOnRemote, amount + ); + require(scaledAmount > 0, "TokenHome: zero scaled amount"); + + // Increase the balance of the TokenRemote instance by the scaled amount. + $._transferredBalances[remoteBlockchainID][remoteTokenTransferrerAddress] += scaledAmount; + + return (scaledAmount, feeAmount); + } + + function _deductSenderBalance( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) private { + TokenHomeStorage storage $ = _getTokenHomeStorage(); + uint256 senderBalance = + $._transferredBalances[remoteBlockchainID][remoteTokenTransferrerAddress]; + require(senderBalance >= amount, "TokenHome: insufficient token transfer balance"); + $._transferredBalances[remoteBlockchainID][remoteTokenTransferrerAddress] = + senderBalance - amount; + } + + function _validateSendAndCallInput( + SendAndCallInput memory input + ) private pure { + require(input.recipientContract != address(0), "TokenHome: zero recipient contract address"); + require(input.requiredGasLimit > 0, "TokenHome: zero required gas limit"); + require(input.recipientGasLimit > 0, "TokenHome: zero recipient gas limit"); + require( + input.recipientGasLimit < input.requiredGasLimit, + "TokenHome: invalid recipient gas limit" + ); + require(input.fallbackRecipient != address(0), "TokenHome: zero fallback recipient address"); + require(input.secondaryFee == 0, "TokenHome: non-zero secondary fee"); + } + + function _validateSendTokensInput( + SendTokensInput memory input + ) private pure { + require(input.recipient != address(0), "TokenHome: zero recipient address"); + require(input.requiredGasLimit > 0, "TokenHome: zero required gas limit"); + require(input.secondaryFee == 0, "TokenHome: non-zero secondary fee"); + } +} diff --git a/icm-contracts/contracts/ictt/TokenHome/interfaces/IERC20TokenHome.sol b/icm-contracts/contracts/ictt/TokenHome/interfaces/IERC20TokenHome.sol new file mode 100644 index 000000000..9e5694032 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/interfaces/IERC20TokenHome.sol @@ -0,0 +1,30 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IERC20TokenTransferrer} from "../../interfaces/IERC20TokenTransferrer.sol"; +import {ITokenHome} from "./ITokenHome.sol"; + +/** + * @notice Interface for a ERC20 token "home" contract that locks its specified ERC20 + * token on its chain to be transferred to supported remote token transfer contracts on other chains. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface IERC20TokenHome is IERC20TokenTransferrer, ITokenHome { + /** + * @notice Adds collateral to the home token transfer contract for the specified TokenRemote instance. If more value is provided + * than the amount of collateral needed, the excess amount is returned to the caller. + * @param remoteBlockchainID The blockchain ID of the TokenRemote instance to add collateral for. + * @param remoteTokenTransferrerAddress The address of the TokenRemote instance to add collateral for on the {remoteBlockchainID}. + * @param amount Amount of tokens to add as collateral. + */ + function addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) external; +} diff --git a/icm-contracts/contracts/ictt/TokenHome/interfaces/INativeTokenHome.sol b/icm-contracts/contracts/ictt/TokenHome/interfaces/INativeTokenHome.sol new file mode 100644 index 000000000..72e4ae138 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/interfaces/INativeTokenHome.sol @@ -0,0 +1,29 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {INativeTokenTransferrer} from "../../interfaces/INativeTokenTransferrer.sol"; +import {ITokenHome} from "./ITokenHome.sol"; + +/** + * @notice Interface for a native token "home" contract that locks the native token + * on its chain to be transferred to supported remote token transfer contracts on other chains. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface INativeTokenHome is INativeTokenTransferrer, ITokenHome { + /** + * @notice Adds collateral to the home token transfer contract for the specified TokenRemote instance. If more value is provided + * than the amount of collateral needed, the excess amount is returned to the caller. + * @param remoteBlockchainID The blockchain ID of the remote token transfer contract to add collateral for. + * @param remoteTokenTransferrerAddress The address of the remote token transfer contract to add collateral for on + * the {remoteBlockchainID}. + */ + function addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress + ) external payable; +} diff --git a/icm-contracts/contracts/ictt/TokenHome/interfaces/ITokenHome.sol b/icm-contracts/contracts/ictt/TokenHome/interfaces/ITokenHome.sol new file mode 100644 index 000000000..984a217aa --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenHome/interfaces/ITokenHome.sol @@ -0,0 +1,69 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + ITokenTransferrer, + SendTokensInput, + SendAndCallInput +} from "../../interfaces/ITokenTransferrer.sol"; + +/** + * @notice Each {ITokenRemote} instance registers with the home contract, and provides settings for transferring + * to the remote token transfer contract. + * @param registered Whether the remote token transferrer is registered + * @param collateralNeeded The amount of tokens that must be first added as collateral, + * through {addCollateral} calls, before tokens can be transferred to the remote token transferrer. + * @param tokenMultiplier The scaling factor for the amount of tokens to be transferred to the remote. + * @param multiplyOnRemote Whether the {tokenMultiplier} should be applied when transferring tokens to + * the remote (multiplyOnRemote=true), or when transferring tokens back to the home (multiplyOnRemote=false). + */ +struct RemoteTokenTransferrerSettings { + bool registered; + uint256 collateralNeeded; + uint256 tokenMultiplier; + bool multiplyOnRemote; +} +/** + * @dev Interface for a "home" token transferrer contract that locks a specific token + * on its chain to be transferred to supported "remote" token transferrer contracts on other chains. + */ + +interface ITokenHome is ITokenTransferrer { + /** + * @dev Emitted when tokens are added as collateral for a given {ITokenRemote} instance. + * The event emits a {remaining} value of 0 when the {ITokenRemote} instance is fully collateralized. + */ + event CollateralAdded( + bytes32 indexed remoteBlockchainID, + address indexed remoteTokenTransferrerAddress, + uint256 amount, + uint256 remaining + ); + + /** + * @notice Emitted when a new {ITokenRemote} instance is registered with the token transferrer. + */ + event RemoteRegistered( + bytes32 indexed remoteBlockchainID, + address indexed remoteTokenTransferrerAddress, + uint256 initialCollateralNeeded, + uint8 tokenDecimals + ); + + /** + * @notice Emitted when tokens are routed from a multi-hop send message to another chain. + */ + event TokensRouted(bytes32 indexed teleporterMessageID, SendTokensInput input, uint256 amount); + + /** + * @notice Emitted when tokens are routed from a mulit-hop send message, + * with calldata for a contract recipient, to another chain. + */ + event TokensAndCallRouted( + bytes32 indexed teleporterMessageID, SendAndCallInput input, uint256 amount + ); +} diff --git a/icm-contracts/contracts/ictt/TokenRemote/ERC20TokenRemote.sol b/icm-contracts/contracts/ictt/TokenRemote/ERC20TokenRemote.sol new file mode 100644 index 000000000..f01fc8a10 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenRemote/ERC20TokenRemote.sol @@ -0,0 +1,26 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ERC20TokenRemoteUpgradeable} from "./ERC20TokenRemoteUpgradeable.sol"; +import {TokenRemoteSettings} from "./interfaces/ITokenRemote.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title ERC20TokenRemote + * @notice A non-upgradeable version of {ERC20TokenRemoteUpgradeable} that calls the parent upgradeable contract's initialize function. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract ERC20TokenRemote is ERC20TokenRemoteUpgradeable { + constructor( + TokenRemoteSettings memory settings, + string memory tokenName, + string memory tokenSymbol, + uint8 tokenDecimals + ) ERC20TokenRemoteUpgradeable(ICMInitializable.Allowed) { + initialize(settings, tokenName, tokenSymbol, tokenDecimals); + } +} diff --git a/icm-contracts/contracts/ictt/TokenRemote/ERC20TokenRemoteUpgradeable.sol b/icm-contracts/contracts/ictt/TokenRemote/ERC20TokenRemoteUpgradeable.sol new file mode 100644 index 000000000..62f28f846 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenRemote/ERC20TokenRemoteUpgradeable.sol @@ -0,0 +1,238 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenRemote} from "./TokenRemote.sol"; +import {TokenRemoteSettings} from "./interfaces/ITokenRemote.sol"; +import {IERC20TokenTransferrer} from "../interfaces/IERC20TokenTransferrer.sol"; +import {IERC20SendAndCallReceiver} from "../interfaces/IERC20SendAndCallReceiver.sol"; +import { + SendTokensInput, + SendAndCallInput, + SingleHopCallMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/ERC20.sol"; +import {ERC20Upgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/token/ERC20/ERC20Upgradeable.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {CallUtils} from "@utilities/CallUtils.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title ERC20TokenRemoteUpgradeable + * @notice This contract is an {IERC20TokenTransferrer} that receives tokens from its specifed {TokenHome} instance, + * and represents the received tokens with an ERC20 token on this chain. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract ERC20TokenRemoteUpgradeable is IERC20TokenTransferrer, ERC20Upgradeable, TokenRemote { + // solhint-disable private-vars-leading-underscore + /** + * @dev Namespace storage slots following the ERC-7201 standard to prevent + * storage collisions between upgradeable contracts. + * + * @custom:storage-location erc7201:avalanche-ictt.storage.ERC20TokenRemote + */ + struct ERC20TokenRemoteStorage { + uint8 _decimals; + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Storage slot computed based off ERC-7201 formula + * keccak256(abi.encode(uint256(keccak256("avalanche-ictt.storage.ERC20TokenRemote")) - 1)) & ~bytes32(uint256(0xff)); + */ + bytes32 public constant ERC20_TOKEN_REMOTE_STORAGE_LOCATION = + 0x9b9029a3537fcf0e984763da4ac33bbf592a3462819171bf424e91cf62622300; + + // solhint-disable ordering + function _getERC20TokenRemoteStorage() + private + pure + returns (ERC20TokenRemoteStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := ERC20_TOKEN_REMOTE_STORAGE_LOCATION + } + } + + constructor( + ICMInitializable init + ) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initializes this token TokenRemote instance to receive tokens from the specified TokenHome instance, + * and represents the received tokens with an ERC20 token on this chain. + * @param settings Constructor settings for this token TokenRemote instance. + * @param tokenName The name of the ERC20 token. + * @param tokenSymbol The symbol of the ERC20 token. + * @param tokenDecimals The number of decimals for the ERC20 token. + */ + function initialize( + TokenRemoteSettings memory settings, + string memory tokenName, + string memory tokenSymbol, + uint8 tokenDecimals + ) public initializer { + __ERC20TokenRemote_init(settings, tokenName, tokenSymbol, tokenDecimals); + } + + // solhint-disable-next-line func-name-mixedcase + function __ERC20TokenRemote_init( + TokenRemoteSettings memory settings, + string memory tokenName, + string memory tokenSymbol, + uint8 tokenDecimals + ) internal onlyInitializing { + __ERC20_init(tokenName, tokenSymbol); + __TokenRemote_init(settings, 0, tokenDecimals); + __ERC20TokenRemote_init_unchained(tokenDecimals); + } + + // solhint-disable-next-line func-name-mixedcase + function __ERC20TokenRemote_init_unchained( + uint8 tokenDecimals + ) internal { + _getERC20TokenRemoteStorage()._decimals = tokenDecimals; + } + // solhint-enable ordering + + /** + * @dev See {IERC20TokenTransferrer-send} + * + * Note: For transfers to an {input.destinationBlockchainID} that is not the {tokenHomeBlockchainID}, + * a multi-hop transfer is performed, where the tokens are sent back to the token TokenHome instance + * first to check for token transfer balance, and then routed to the final destination TokenRemote instance. + */ + function send(SendTokensInput calldata input, uint256 amount) external { + _send(input, amount); + } + + /** + * @dev See {IERC20TokenTransferrer-sendAndCall} + */ + function sendAndCall(SendAndCallInput calldata input, uint256 amount) external { + _sendAndCall(input, amount); + } + + /** + * @dev See {ERC20-decimals} + */ + function decimals() public view override returns (uint8) { + ERC20TokenRemoteStorage storage $ = _getERC20TokenRemoteStorage(); + return $._decimals; + } + + /** + * @dev See {TokenRemote-_withdraw} + */ + function _withdraw(address recipient, uint256 amount) internal virtual override { + emit TokensWithdrawn(recipient, amount); + _mint(recipient, amount); + } + + /** + * @dev See {TokenRemote-_burn} + * + * Spends the allowance the caller has given to this contract, and + * calls {ERC20-_burn} to burn tokens from the sender. + * + * Note: The amount returned must match the amount credited as a result of the burn. + * For a standard ERC20 implementation such as this contract, that is equal to the full amount given. + * Child contracts with different {_burn} implementations may need to override this + * implemenation to ensure the amount returned is correct. + */ + function _burn( + uint256 amount + ) internal virtual override returns (uint256) { + _spendAllowance(_msgSender(), address(this), amount); + _burn(_msgSender(), amount); + return amount; + } + + /** + * @dev See {TokenRemote-_handleSendAndCall} + * + * Mints the tokens to this contract, approves the recipient contract to spend them, + * and calls {IERC20SendAndCallReceiver-receiveTokens} on the recipient contract. + * If the call fails or doesn't spend all of the tokens, the remaining amount is + * sent to the fallback recipient. + */ + function _handleSendAndCall( + SingleHopCallMessage memory message, + uint256 amount + ) internal virtual override { + // Mint the tokens to this contract address. + _mint(address(this), amount); + + // Approve the recipient contract to spend the amount. + _approve(address(this), message.recipientContract, amount); + + // Encode the call to {IERC20SendAndCallReceiver-receiveTokens} + bytes memory payload = abi.encodeCall( + IERC20SendAndCallReceiver.receiveTokens, + ( + message.sourceBlockchainID, + message.originTokenTransferrerAddress, + message.originSenderAddress, + address(this), + amount, + message.recipientPayload + ) + ); + + // Call the recipient contract with the given payload and gas amount. + bool success = CallUtils._callWithExactGas( + message.recipientGasLimit, message.recipientContract, payload + ); + + // Check what the remaining allowance is to transfer to the fallback recipient. + uint256 remainingAllowance = allowance(address(this), message.recipientContract); + + // Reset the recipient contract allowance to 0. + _approve(address(this), message.recipientContract, 0); + + if (success) { + emit CallSucceeded(message.recipientContract, amount); + } else { + emit CallFailed(message.recipientContract, amount); + } + + // Transfer any remaining allowance to the fallback recipient. This will be the + // full amount if the call failed. + if (remainingAllowance > 0) { + _transfer(address(this), message.fallbackRecipient, remainingAllowance); + } + } + + /** + * @notice See {TokenRemote-_handleFees} + * + * If the {feeTokenAddress} is this contract, use the internal ERC20 calls + * to transfer the tokens directly. Otherwise, use the {SafeERC20TransferFrom} library + * to transfer the tokens. + */ + function _handleFees( + address feeTokenAddress, + uint256 feeAmount + ) internal virtual override returns (uint256) { + if (feeAmount == 0) { + return 0; + } + // If the {feeTokenAddress} is this contract, then just deposit the tokens directly. + if (feeTokenAddress == address(this)) { + _spendAllowance(_msgSender(), address(this), feeAmount); + _transfer(_msgSender(), address(this), feeAmount); + return feeAmount; + } + return + SafeERC20TransferFrom.safeTransferFrom(IERC20(feeTokenAddress), _msgSender(), feeAmount); + } +} diff --git a/icm-contracts/contracts/ictt/TokenRemote/NativeTokenRemote.sol b/icm-contracts/contracts/ictt/TokenRemote/NativeTokenRemote.sol new file mode 100644 index 000000000..8e81d694a --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenRemote/NativeTokenRemote.sol @@ -0,0 +1,31 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {NativeTokenRemoteUpgradeable} from "./NativeTokenRemoteUpgradeable.sol"; +import {TokenRemoteSettings} from "./interfaces/ITokenRemote.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title NativeTokenRemote + * @notice A non-upgradeable version of {NativeTokenRemoteUpgradeable} that calls the parent upgradeable contract's initialize function. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract NativeTokenRemote is NativeTokenRemoteUpgradeable { + constructor( + TokenRemoteSettings memory settings, + string memory nativeAssetSymbol, + uint256 initialReserveImbalance, + uint256 burnedFeesReportingRewardPercentage + ) NativeTokenRemoteUpgradeable(ICMInitializable.Allowed) { + initialize( + settings, + nativeAssetSymbol, + initialReserveImbalance, + burnedFeesReportingRewardPercentage + ); + } +} diff --git a/icm-contracts/contracts/ictt/TokenRemote/NativeTokenRemoteUpgradeable.sol b/icm-contracts/contracts/ictt/TokenRemote/NativeTokenRemoteUpgradeable.sol new file mode 100644 index 000000000..090992e11 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenRemote/NativeTokenRemoteUpgradeable.sol @@ -0,0 +1,420 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenRemote} from "./TokenRemote.sol"; +import {TokenRemoteSettings} from "./interfaces/ITokenRemote.sol"; +import {INativeTokenRemote} from "./interfaces/INativeTokenRemote.sol"; +import {INativeSendAndCallReceiver} from "../interfaces/INativeSendAndCallReceiver.sol"; +import {IWrappedNativeToken} from "../interfaces/IWrappedNativeToken.sol"; +import { + SendTokensInput, + SendAndCallInput, + TransferrerMessageType, + TransferrerMessage, + SingleHopSendMessage, + SingleHopCallMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {TeleporterFeeInfo, TeleporterMessageInput} from "@teleporter/ITeleporterMessenger.sol"; +import {INativeMinter} from "@subnet-evm/INativeMinter.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/ERC20.sol"; +import {ERC20Upgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/token/ERC20/ERC20Upgradeable.sol"; +import {Address} from "@openzeppelin/contracts@5.0.2/utils/Address.sol"; +import {CallUtils} from "@utilities/CallUtils.sol"; +import {TokenScalingUtils} from "@utilities/TokenScalingUtils.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @title NativeTokenRemoteUpgradeable + * @notice This contract is an {INativeTokenRemote} that receives tokens from its specifed {TokenHome} instance, + * and represents the received tokens as the native token on this chain. + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract NativeTokenRemoteUpgradeable is + INativeTokenRemote, + IWrappedNativeToken, + ERC20Upgradeable, + TokenRemote +{ + using Address for address payable; + + // solhint-disable private-vars-leading-underscore + /** + * @dev Namespace storage slots following the ERC-7201 standard to prevent + * storage collisions between upgradeable contracts. + * + * @custom:storage-location erc7201:avalanche-ictt.storage.NativeTokenRemote + */ + struct NativeTokenRemoteStorage { + /** + * @notice Percentage of burned transaction fees that will be rewarded to a relayer delivering + * the message created by calling calling reportBurnedTxFees(). + */ + uint256 _burnedFeesReportingRewardPercentage; + /** + * @notice Total number of tokens minted by this contract through the native minter precompile. + */ + uint256 _totalMinted; + /** + * @notice The balance of BURNED_TX_FEES_ADDRESS the last time burned fees were reported to the TokenHome instance. + */ + uint256 _lastestBurnedFeesReported; + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Storage slot computed based off ERC-7201 formula + * keccak256(abi.encode(uint256(keccak256("avalanche-ictt.storage.NativeTokenRemote")) - 1)) & ~bytes32(uint256(0xff)); + */ + bytes32 public constant NATIVE_TOKEN_REMOTE_STORAGE_LOCATION = + 0x69a5f7616543528c4fbe43f410b1034bd6da4ba06c25bedf04617268014cf500; + + // solhint-disable ordering + function _getNativeTokenRemoteStorage() + private + pure + returns (NativeTokenRemoteStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := NATIVE_TOKEN_REMOTE_STORAGE_LOCATION + } + } + + /** + * @notice The address where the burned transaction fees are credited. + * + * @dev Defined as BLACKHOLE_ADDRESS at + * https://github.com/ava-labs/subnet-evm/blob/v0.6.0/constants/constants.go + * C-Chain value found at https://github.com/ava-labs/coreth/blob/v0.13.2/constants/constants.go + * It is a system-reserved address by default in subnet-evm and coreth, and transfers cannot be sent here manually. + */ + address public constant BURNED_TX_FEES_ADDRESS = 0x0100000000000000000000000000000000000000; + + /** + * @notice The address where native tokens are sent in order to be burned to transfer to other chains. + * + * @dev This address is distinct from {BURNED_TX_FEES_ADDRESS} so that the amount of burned transaction + * fees and burned transferred amounts can be tracked separately. + * This address was chosen arbitrarily. + */ + address public constant BURNED_FOR_TRANSFER_ADDRESS = 0x0100000000000000000000000000000000010203; + + /** + * @notice Address used to blackhole funds on the home chain, effectively burning them. + * + * @dev When reporting burned transaction fee amounts, this address is used as the recipient + * address for the funds to be sent to be burned on the home chain. + * This address was chosen arbitrarily. + */ + address public constant HOME_CHAIN_BURN_ADDRESS = 0x0100000000000000000000000000000000010203; + + /** + * @notice The native minter precompile. + */ + INativeMinter public constant NATIVE_MINTER = + INativeMinter(0x0200000000000000000000000000000000000001); + + /** + * @dev When modifier is used, the function can only be called after the contract is fully collelateralized, + * accounting for the initialReserveImbalance. + */ + modifier onlyWhenCollateralized() { + require(getIsCollateralized(), "NativeTokenRemote: contract undercollateralized"); + _; + } + + constructor( + ICMInitializable init + ) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initializes this token TokenRemote instance to receive tokens from the specified TokenHome instance, + * and represents the received tokens with the native token on this chain. + * @param settings Constructor settings for this token TokenRemote instance. + * @param nativeAssetSymbol The symbol of the native asset. + * @param initialReserveImbalance The initial reserve imbalance that must be collateralized before minting. + * @param burnedFeesReportingRewardPercentage The percentage of burned transaction fees + * that will be rewarded to sender of the report. + */ + function initialize( + TokenRemoteSettings memory settings, + string memory nativeAssetSymbol, + uint256 initialReserveImbalance, + uint256 burnedFeesReportingRewardPercentage + ) public initializer { + __NativeTokenRemote_init( + settings, + nativeAssetSymbol, + initialReserveImbalance, + burnedFeesReportingRewardPercentage + ); + } + + // solhint-disable-next-line func-name-mixedcase + function __NativeTokenRemote_init( + TokenRemoteSettings memory settings, + string memory nativeAssetSymbol, + uint256 initialReserveImbalance, + uint256 burnedFeesReportingRewardPercentage + ) internal onlyInitializing { + require(initialReserveImbalance != 0, "NativeTokenRemote: zero initial reserve imbalance"); + __ERC20_init(nativeAssetSymbol, nativeAssetSymbol); + __TokenRemote_init(settings, initialReserveImbalance, 18); + __NativeTokenRemote_init_unchained(burnedFeesReportingRewardPercentage); + } + + // solhint-disable-next-line func-name-mixedcase + function __NativeTokenRemote_init_unchained( + uint256 burnedFeesReportingRewardPercentage + ) internal onlyInitializing { + require(burnedFeesReportingRewardPercentage < 100, "NativeTokenRemote: invalid percentage"); + _getNativeTokenRemoteStorage()._burnedFeesReportingRewardPercentage = + burnedFeesReportingRewardPercentage; + } + // solhint-enable ordering + + /** + * @dev Receives native token with no calldata provided. The tokens are credited to the sender's + * wrapped native token balance. + */ + receive() external payable { + deposit(); + } + + /** + * @dev Fallback function for receiving native tokens. The tokens are credited to the sender's + * wrapped native token balance. + */ + fallback() external payable { + deposit(); + } + + /** + * @dev See {INativeTokenTransferrer-send}. + */ + function send( + SendTokensInput calldata input + ) external payable onlyWhenCollateralized { + _send(input, msg.value); + } + + /** + * @dev See {INativeTokenTransferrer-sendAndCall} + */ + function sendAndCall( + SendAndCallInput calldata input + ) external payable onlyWhenCollateralized { + _sendAndCall(input, msg.value); + } + + /** + * @dev See {INativeTokenRemote-reportBurnedTxFees}. + */ + function reportBurnedTxFees( + uint256 requiredGasLimit + ) external sendNonReentrant { + NativeTokenRemoteStorage storage $ = _getNativeTokenRemoteStorage(); + uint256 burnAddressBalance = BURNED_TX_FEES_ADDRESS.balance; + require( + burnAddressBalance > $._lastestBurnedFeesReported, + "NativeTokenRemote: burn address balance not greater than last report" + ); + + uint256 burnedDifference = burnAddressBalance - $._lastestBurnedFeesReported; + uint256 reward = (burnedDifference * $._burnedFeesReportingRewardPercentage) / 100; + uint256 burnedTxFees = burnedDifference - reward; + $._lastestBurnedFeesReported = burnAddressBalance; + + if (reward > 0) { + // Re-mint the native tokens to this contract, and then deposit them to be the wrapped + // native token (ERC20) representation, such that they can be used as a Teleporter + // message fee. + _mintNativeCoin(address(this), reward); + _mint(address(this), reward); + } + + // Check that the scaled amount on the TokenHome instance will be non-zero. + require( + TokenScalingUtils.removeTokenScale( + getTokenMultiplier(), getMultiplyOnRemote(), burnedTxFees + ) > 0, + "NativeTokenRemote: zero scaled amount to report burn" + ); + + // Report the burned amount to the TokenHome instance. + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_SEND, + payload: abi.encode( + SingleHopSendMessage({recipient: HOME_CHAIN_BURN_ADDRESS, amount: burnedTxFees}) + ) + }); + + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: getTokenHomeBlockchainID(), + destinationAddress: getTokenHomeAddress(), + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(this), amount: reward}), + requiredGasLimit: requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit ReportBurnedTxFees({teleporterMessageID: messageID, feesBurned: burnedTxFees}); + } + + /** + * @dev See {IWrappedNativeToken-withdraw}. + * + * Note: {IWrappedNativeToken-withdraw} should not be confused with {TokenRemote-_withdraw}. + * {IWrappedNativeToken-withdraw} is the external method to redeem a wrapped native token (ERC20) balance + * for the native token itself. {TokenRemote-_withdraw} is the internal method used when + * processing token transfers. + */ + function withdraw( + uint256 amount + ) external { + emit Withdrawal(_msgSender(), amount); + _burn(_msgSender(), amount); + payable(_msgSender()).sendValue(amount); + } + + /** + * @dev See {IWrappedNativeToken-deposit}. + */ + function deposit() public payable { + emit Deposit(_msgSender(), msg.value); + _mint(_msgSender(), msg.value); + } + + /** + * @dev See {INativeTokenRemote-totalNativeAssetSupply}. + * + * Note: {INativeTokenRemote-totalNativeAssetSupply} should not be confused with {IERC20-totalSupply} + * {INativeTokenRemote-totalNativeAssetSupply} returns the supply of the native asset of the chain, + * accounting for the amounts that have been transferred in and out of the chain as well as burnt transaction + * fees. The {initialReserveBalance} is included in this supply since it is in circulation on this + * chain even prior to it being backed by collateral on the TokenHome instance. + * {IERC20-totalSupply} returns the supply of the native asset held by this contract + * that is represented as an ERC20. + */ + function totalNativeAssetSupply() public view returns (uint256) { + NativeTokenRemoteStorage storage $ = _getNativeTokenRemoteStorage(); + uint256 burned = BURNED_TX_FEES_ADDRESS.balance + BURNED_FOR_TRANSFER_ADDRESS.balance; + uint256 created = $._totalMinted + getInitialReserveImbalance(); + return created - burned; + } + + function getTotalMinted() external view returns (uint256) { + return _getNativeTokenRemoteStorage()._totalMinted; + } + + /** + * @dev See {TokenRemote-_withdraw} + */ + function _withdraw(address recipient, uint256 amount) internal virtual override { + emit TokensWithdrawn(recipient, amount); + _mintNativeCoin(recipient, amount); + } + + /** + * @dev See {TokenRemote-_burn} + * + * This is the internal {_burn} method called when transferring tokens to another chain. + * The tokens to be burnt are already held by this contract. To burn the tokens, send the + * native token amount to the BURNED_FOR_TRANSFER_ADDRESS. + */ + function _burn( + uint256 amount + ) internal virtual override returns (uint256) { + payable(BURNED_FOR_TRANSFER_ADDRESS).sendValue(amount); + return amount; + } + + /** + * @dev See {TokenRemote-_handleSendAndCall} + * + * Mints the tokens to this contract, and send them to the recipient contract as a + * part of the call to {INativeSendAndCallReceiver-receiveTokens} on the recipient contract. + * If the call fails, the amount is sent to the fallback recipient. + * + * Note: If the recipient contract does not properly handle the full msg.value sent, + * the balance can be locked in the recipient contract. Receiving contracts must make + * sure to properly handle the balance to ensure it does not get locked improperly. + */ + function _handleSendAndCall( + SingleHopCallMessage memory message, + uint256 amount + ) internal virtual override { + // Mint the tokens to this contract address. + _mintNativeCoin(address(this), amount); + + // Encode the call to {INativeSendAndCallReceiver-receiveTokens} + bytes memory payload = abi.encodeCall( + INativeSendAndCallReceiver.receiveTokens, + ( + message.sourceBlockchainID, + message.originTokenTransferrerAddress, + message.originSenderAddress, + message.recipientPayload + ) + ); + + // Call the recipient contract with the given payload, gas amount, and value. + bool success = CallUtils._callWithExactGasAndValue( + message.recipientGasLimit, amount, message.recipientContract, payload + ); + + // If the call failed, send the funds to the fallback recipient. + if (success) { + emit CallSucceeded(message.recipientContract, amount); + } else { + emit CallFailed(message.recipientContract, amount); + payable(message.fallbackRecipient).sendValue(amount); + } + } + + /** + * @notice See {TokenRemote-_handleFees} + * + * If the {feeTokenAddress} is this contract, use the internal ERC20 calls + * to transfer the tokens directly. Otherwise, use the {SafeERC20TransferFrom} library + * to transfer the tokens. + */ + function _handleFees( + address feeTokenAddress, + uint256 feeAmount + ) internal virtual override returns (uint256) { + if (feeAmount == 0) { + return 0; + } + // If the {feeTokenAddress} is this contract, then just deposit the tokens directly. + if (feeTokenAddress == address(this)) { + _spendAllowance(_msgSender(), address(this), feeAmount); + _transfer(_msgSender(), address(this), feeAmount); + return feeAmount; + } + return + SafeERC20TransferFrom.safeTransferFrom(IERC20(feeTokenAddress), _msgSender(), feeAmount); + } + + /** + * @dev Mints coins to the recipient through the NativeMinter precompile. + */ + function _mintNativeCoin(address recipient, uint256 amount) private { + NativeTokenRemoteStorage storage $ = _getNativeTokenRemoteStorage(); + $._totalMinted += amount; + // Calls NativeMinter precompile through INativeMinter interface. + NATIVE_MINTER.mintNativeCoin(recipient, amount); + } +} diff --git a/icm-contracts/contracts/ictt/TokenRemote/TokenRemote.sol b/icm-contracts/contracts/ictt/TokenRemote/TokenRemote.sol new file mode 100644 index 000000000..c507dce71 --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenRemote/TokenRemote.sol @@ -0,0 +1,721 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ITokenRemote, TokenRemoteSettings} from "./interfaces/ITokenRemote.sol"; +import { + SendTokensInput, + SendAndCallInput, + TransferrerMessageType, + TransferrerMessage, + SingleHopSendMessage, + SingleHopCallMessage, + MultiHopSendMessage, + MultiHopCallMessage, + RegisterRemoteMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {TeleporterMessageInput, TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; +import {TeleporterRegistryOwnableAppUpgradeable} from + "@teleporter/registry/TeleporterRegistryOwnableAppUpgradeable.sol"; +import {IWarpMessenger} from "@subnet-evm/IWarpMessenger.sol"; +import {SendReentrancyGuardUpgradeable} from "@utilities/SendReentrancyGuardUpgradeable.sol"; +import {TokenScalingUtils} from "@utilities/TokenScalingUtils.sol"; + +/** + * @title TokenRemote + * @dev Abstract contract for a token transferrer remote that receives tokens from its specified token TokenHome instance, and + * allows for burning that token to redeem the backing asset on the home chain, or transferring to other remotes. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract TokenRemote is + ITokenRemote, + TeleporterRegistryOwnableAppUpgradeable, + SendReentrancyGuardUpgradeable +{ + // solhint-disable private-vars-leading-underscore + /** + * @dev Namespace storage slots following the ERC-7201 standard to prevent + * storage collisions between upgradeable contracts. + * + * @custom:storage-location erc7201:avalanche-ictt.storage.TokenRemote + */ + struct TokenRemoteStorage { + /// @notice The blockchain ID of the chain this contract is deployed on. + bytes32 _blockchainID; + /// @notice The blockchain ID of the TokenHome instance this contract receives tokens from. + bytes32 _tokenHomeBlockchainID; + /// @notice The address of the TokenHome instance this contract receives tokens from on the {tokenHomeBlockchainID}. + address _tokenHomeAddress; + /** + * @notice The number of decimal places in the denomination of the home + * token. + * @dev Used to derive tokenMultiplier and multiplyOnRemote. + */ + uint8 _homeTokenDecimals; + /** + * @notice The number of decimal places in the denomination of the remote token. + * @dev Used to derive tokenMultiplier and multiplyOnRemote. + */ + uint8 _tokenDecimals; + /** + * @notice tokenMultiplier allows this contract to scale the number of tokens it sends/receives to/from + * its token TokenHome instance. + * + * @dev This is used to normalize the number of decimal places between the token home asset and the + * token remote asset. It is derived from home and remote token decimals values passed in the constructor. + */ + uint256 _tokenMultiplier; + /** + * @notice If {multiplyOnRemote} is true, the home token amount will be multiplied by {tokenMultiplier} when tokens + * are transferred from the home into this remote, and divided by {tokenMultiplier} when tokens are transferred from + * this remote back to its home. + * If {multiplyOnRemote} is false, the home token amount value will be divided by {tokenMultiplier} when tokens + * are transferred from the home into this remote, and multiplied by {tokenMultiplier} when tokens are transferred + * from this remote back to its home. + */ + bool _multiplyOnRemote; + /** + * @notice Initial reserve imbalance that the token for this TokenRemote instance starts with. The home contract must + * collateralize a corresonding amount of home tokens before tokens can be minted on this contract. + */ + uint256 _initialReserveImbalance; + /** + * @notice Whether or not the contract is known to be fully collateralized. + */ + bool _isCollateralized; + /** + * @notice Whether or not the contract is known to be registered with its specified home contract. + * This is set to true when the first message is received from the home contract. Note that {isRegistered} + * will still be false after the remote contract is registered on the home contract until the first + * message is received back from that contract. + */ + bool _isRegistered; + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Storage slot computed based off ERC-7201 formula + * keccak256(abi.encode(uint256(keccak256("avalanche-ictt.storage.TokenRemote")) - 1)) & ~bytes32(uint256(0xff)); + */ + bytes32 public constant TOKEN_REMOTE_STORAGE_LOCATION = + 0x600d6a9b283d1eda563de594ce4843869b6f128a4baa222422ed94a60b0cef00; + + // solhint-disable ordering + function _getTokenRemoteStorage() private pure returns (TokenRemoteStorage storage $) { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := TOKEN_REMOTE_STORAGE_LOCATION + } + } + + /** + * @notice Fixed gas cost for executing a multi-hop send message on the token home contract, + * before forwarding to the destination token TokenRemote instance. Note that for certain home implementations, + * a higher required gas limit may be needed depending on the gas expenditure of the external call to the + * token contract to approve the spending of the optional secondary fee amount. + */ + uint256 public constant MULTI_HOP_SEND_REQUIRED_GAS = 340_000; + + /** + * @notice Fixed gas cost for executing a multi-hop call message on the token home contract, + * before forwarding to the destination token TokenRemote instance. Note that for certain home implementations, + * a higher required gas limit may be needed depending on the gas expenditure of the external call to the + * token contract to approve the spending of the optional secondary fee amount. + */ + uint256 public constant MULTI_HOP_CALL_REQUIRED_GAS = 350_000; + + /** + * @notice The amount of gas added to the required gas limit for a multi-hop call message + * for each 32-byte word of the recipient payload. + */ + uint256 public constant MULTI_HOP_CALL_GAS_PER_WORD = 1_500; + + /** + * @notice Fixed gas cost for registering the remote contract on the home contract. + */ + uint256 public constant REGISTER_REMOTE_REQUIRED_GAS = 130_000; + + /** + * @notice Initializes this token TokenRemote instance. + * @param settings The settings for the token TokenRemote instance. + * @param initialReserveImbalance_ The initial reserve imbalance that must be collateralized before minting. + * @param tokenDecimals The number of decimal places in the denomination of the remote token. + */ + // solhint-disable ordering + // solhint-disable-next-line func-name-mixedcase + function __TokenRemote_init( + TokenRemoteSettings memory settings, + uint256 initialReserveImbalance_, + uint8 tokenDecimals + ) internal onlyInitializing { + __TeleporterRegistryOwnableApp_init( + settings.teleporterRegistryAddress, + settings.teleporterManager, + settings.minTeleporterVersion + ); + __SendReentrancyGuard_init(); + __TokenRemote_init_unchained(settings, initialReserveImbalance_, tokenDecimals); + } + + // solhint-disable-next-line func-name-mixedcase + function __TokenRemote_init_unchained( + TokenRemoteSettings memory settings, + uint256 initialReserveImbalance_, + uint8 tokenDecimals + ) internal onlyInitializing { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + $._blockchainID = + IWarpMessenger(0x0200000000000000000000000000000000000005).getBlockchainID(); + require( + settings.tokenHomeBlockchainID != bytes32(0), + "TokenRemote: zero token home blockchain ID" + ); + require( + settings.tokenHomeBlockchainID != $._blockchainID, + "TokenRemote: cannot deploy to same blockchain as token home" + ); + require(settings.tokenHomeAddress != address(0), "TokenRemote: zero token home address"); + require( + settings.tokenHomeDecimals <= TokenScalingUtils.MAX_TOKEN_DECIMALS, + "TokenRemote: token home decimals too high" + ); + require( + tokenDecimals <= TokenScalingUtils.MAX_TOKEN_DECIMALS, + "TokenRemote: token decimals too high" + ); + $._tokenHomeBlockchainID = settings.tokenHomeBlockchainID; + $._tokenHomeAddress = settings.tokenHomeAddress; + $._initialReserveImbalance = initialReserveImbalance_; + $._isCollateralized = initialReserveImbalance_ == 0; + $._homeTokenDecimals = settings.tokenHomeDecimals; + $._tokenDecimals = tokenDecimals; + ($._tokenMultiplier, $._multiplyOnRemote) = + TokenScalingUtils.deriveTokenMultiplierValues(settings.tokenHomeDecimals, tokenDecimals); + } + // solhint-enable ordering + + /** + * @notice Sends a message to the contract's specified token TokenHome instance to register this remote + * instance. TokenRemote instances must be registered with their home contract prior to being able to receive + * tokens from them. + */ + function registerWithHome( + TeleporterFeeInfo calldata feeInfo + ) external virtual { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + require(!$._isRegistered, "TokenRemote: already registered"); + + // Send a message to the token TokenHome instance to register this TokenRemote instance. + RegisterRemoteMessage memory registerMessage = RegisterRemoteMessage({ + initialReserveImbalance: $._initialReserveImbalance, + homeTokenDecimals: $._homeTokenDecimals, + remoteTokenDecimals: $._tokenDecimals + }); + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.REGISTER_REMOTE, + payload: abi.encode(registerMessage) + }); + + uint256 feeAmount = _handleFees(feeInfo.feeTokenAddress, feeInfo.amount); + _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: $._tokenHomeBlockchainID, + destinationAddress: $._tokenHomeAddress, + feeInfo: TeleporterFeeInfo({feeTokenAddress: feeInfo.feeTokenAddress, amount: feeAmount}), + requiredGasLimit: REGISTER_REMOTE_REQUIRED_GAS, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + } + + /** + * @dev Calculates the number of 32-byte words required to fit a payload of a given length. + * The payloads are padded to have a length that is a multiple of 32. + */ + function calculateNumWords( + uint256 payloadSize + ) public pure returns (uint256) { + // Add 31 to effectively round up to the nearest multiple of 32. + // Right-shift by 5 bits to divide by 32. + return (payloadSize + 31) >> 5; + } + + function getIsCollateralized() public view returns (bool) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + return $._isCollateralized; + } + + function getTokenMultiplier() public view returns (uint256) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + return $._tokenMultiplier; + } + + function getMultiplyOnRemote() public view returns (bool) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + return $._multiplyOnRemote; + } + + function getTokenHomeBlockchainID() public view returns (bytes32) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + return $._tokenHomeBlockchainID; + } + + function getTokenHomeAddress() public view returns (address) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + return $._tokenHomeAddress; + } + + function getInitialReserveImbalance() public view returns (uint256) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + return $._initialReserveImbalance; + } + + function getBlockchainID() public view returns (bytes32) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + return $._blockchainID; + } + // solhint-enable ordering + + /** + * @notice Sends tokens to the specified destination. + * + * @dev Burns the transferred amount, and uses Teleporter to send a cross chain message to the token TokenHome instance. + * Tokens can be sent the token TokenHome instance, or to any TokenRemote instance registered with the home other than this one. + */ + function _send(SendTokensInput calldata input, uint256 amount) internal sendNonReentrant { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + _validateSendTokensInput(input); + if (input.destinationBlockchainID == $._tokenHomeBlockchainID) { + _processSend(input, amount); + } else { + _processSendMultiHop(input, amount); + } + } + + /** + * @notice Sends tokens to the specified recipient contract on the destination blockchain ID by + * calling the {receiveTokens} method of the respective recipient. + * + * @dev Burns the transferred amount, and uses Teleporter to send a cross chain message. + * Tokens and data can be sent to the token TokenHome instance, or to any TokenRemote instance registered with the home + * other than this one. + */ + function _sendAndCall( + SendAndCallInput calldata input, + uint256 amount + ) internal sendNonReentrant { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + _validateSendAndCallInput(input); + + if (input.destinationBlockchainID == $._tokenHomeBlockchainID) { + return _processSendAndCall(input, amount); + } else { + return _processSendAndCallMultiHop(input, amount); + } + } + + /** + * @notice Handles receiving messages from the token TokenHome instance. The supported message types are + * single-hop sends, and single-hop calls. + * + * @dev See {ITeleporterUpgradeable-_receiveTeleporterMessage} + */ + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message + ) internal override { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + require( + sourceBlockchainID == $._tokenHomeBlockchainID, + "TokenRemote: invalid source blockchain ID" + ); + require( + originSenderAddress == $._tokenHomeAddress, "TokenRemote: invalid origin sender address" + ); + TransferrerMessage memory transferrerMessage = abi.decode(message, (TransferrerMessage)); + + // If the contract was not previously known to be registered or collateralized, it is now given that + // the home has sent a message to mint funds. + if (!$._isRegistered || !$._isCollateralized) { + $._isRegistered = true; + $._isCollateralized = true; + } + + // Remote contracts should only ever receive single-hop messages because + // multi-hop messages are always routed through the home contract. + if (transferrerMessage.messageType == TransferrerMessageType.SINGLE_HOP_SEND) { + SingleHopSendMessage memory payload = + abi.decode(transferrerMessage.payload, (SingleHopSendMessage)); + _withdraw(payload.recipient, payload.amount); + } else if (transferrerMessage.messageType == TransferrerMessageType.SINGLE_HOP_CALL) { + // The {sourceBlockchainID}, and {originSenderAddress} specified in the message + // payload will not match the sender of this Teleporter message in the case of a + // multi-hop message. Since Teleporter messages are only received from the specified + // token TokenHome instance, no additional authentication is needed on the payload values. + SingleHopCallMessage memory payload = + abi.decode(transferrerMessage.payload, (SingleHopCallMessage)); + _handleSendAndCall(payload, payload.amount); + } else { + revert("TokenRemote: invalid message type"); + } + } + + /** + * @notice Withdraws tokens to the recipient address. + * @param recipient The address to withdraw tokens to + * @param amount The amount of tokens to withdraw + */ + function _withdraw(address recipient, uint256 amount) internal virtual; + + /** + * @notice Burns the user's tokens to initiate a token transfer. + * @param amount The amount of tokens to burn + * @return The amount of tokens burned, which is the amount to credit + * for the token transfer. + */ + function _burn( + uint256 amount + ) internal virtual returns (uint256); + + /** + * @notice Processes a send and call message by calling the recipient contract. + * @param message The send and call message include recipient calldata + * @param amount The amount of tokens to be sent to the recipient. This amount is assumed to be + * already scaled to the local denomination of this contract. + */ + function _handleSendAndCall( + SingleHopCallMessage memory message, + uint256 amount + ) internal virtual; + + /** + * @notice Handles fees sent to this contract for a token transfer. + * The fee is expected to be approved by the sender for this token transfer contract to use, + * and will be transferred to this contract to allocate for the token transfer. + * @param feeTokenAddress The address of the fee token + * @param feeAmount The amount of the fee + */ + function _handleFees( + address feeTokenAddress, + uint256 feeAmount + ) internal virtual returns (uint256); + + /** + * @dev Prepares tokens to be sent to another chain by handling the + * deposit, burning, and checking that the corresonding amount of + * home tokens is greater than zero. + */ + function _prepareSend( + uint256 amount, + address primaryFeeTokenAddress, + uint256 primaryFee, + uint256 secondaryFee + ) private returns (uint256, uint256) { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + + // Burn the amount of tokens that will be transferred. + amount = _burn(amount); + + // Transfer the primary fee to pay for fees on the first hop. + // The user can specify this contract as {primaryFeeTokenAddress}, + // in which case the fee will be paid on top of the transferred amount. + primaryFee = _handleFees(primaryFeeTokenAddress, primaryFee); + + // The transferred amount must cover the secondary fee, because the secondary fee + // is directly subtracted from the transferred amount on the intermediate (home) chain + // performing the multi-hop, before forwarding to the final destination TokenRemote instance. + require( + TokenScalingUtils.removeTokenScale($._tokenMultiplier, $._multiplyOnRemote, amount) + > TokenScalingUtils.removeTokenScale( + $._tokenMultiplier, $._multiplyOnRemote, secondaryFee + ), + "TokenRemote: insufficient tokens to transfer" + ); + + // Return the amount in this contract's local denomination and the primary fee. + return (amount, primaryFee); + } + + /** + * @dev Sends tokens to the specified destination. + */ + function _processSend(SendTokensInput calldata input, uint256 amount) private { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + _validateSingleHopInput( + input.destinationTokenTransferrerAddress, input.secondaryFee, input.multiHopFallback + ); + + uint256 primaryFee; + (amount, primaryFee) = _prepareSend({ + amount: amount, + primaryFeeTokenAddress: input.primaryFeeTokenAddress, + primaryFee: input.primaryFee, + secondaryFee: input.secondaryFee + }); + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_SEND, + payload: abi.encode(SingleHopSendMessage({recipient: input.recipient, amount: amount})) + }); + + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: $._tokenHomeBlockchainID, + destinationAddress: $._tokenHomeAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensSent(messageID, _msgSender(), input, amount); + } + + /** + * @dev Sends tokens to the specified destination via multi-hop. + */ + function _processSendMultiHop(SendTokensInput calldata input, uint256 amount) private { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + _validateMultiHopInput( + input.destinationBlockchainID, + input.destinationTokenTransferrerAddress, + input.multiHopFallback + ); + + uint256 primaryFee; + (amount, primaryFee) = _prepareSend({ + amount: amount, + primaryFeeTokenAddress: input.primaryFeeTokenAddress, + primaryFee: input.primaryFee, + secondaryFee: input.secondaryFee + }); + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.MULTI_HOP_SEND, + payload: abi.encode( + MultiHopSendMessage({ + destinationBlockchainID: input.destinationBlockchainID, + destinationTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + recipient: input.recipient, + amount: amount, + secondaryFee: input.secondaryFee, + secondaryGasLimit: input.requiredGasLimit, + multiHopFallback: input.multiHopFallback + }) + ) + }); + + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: $._tokenHomeBlockchainID, + destinationAddress: $._tokenHomeAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: primaryFee + }), + requiredGasLimit: MULTI_HOP_SEND_REQUIRED_GAS, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensSent(messageID, _msgSender(), input, amount); + } + + /** + * @dev Sends tokens to the specified recipient contract on the destination blockchain ID by + * calling the {receiveTokens} method of the respective recipient. + */ + function _processSendAndCall(SendAndCallInput calldata input, uint256 amount) private { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + _validateSingleHopInput( + input.destinationTokenTransferrerAddress, input.secondaryFee, input.multiHopFallback + ); + + uint256 primaryFee; + (amount, primaryFee) = _prepareSend({ + amount: amount, + primaryFeeTokenAddress: input.primaryFeeTokenAddress, + primaryFee: input.primaryFee, + secondaryFee: input.secondaryFee + }); + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_CALL, + payload: abi.encode( + SingleHopCallMessage({ + sourceBlockchainID: $._blockchainID, + originTokenTransferrerAddress: address(this), + originSenderAddress: _msgSender(), + recipientContract: input.recipientContract, + amount: amount, + recipientPayload: input.recipientPayload, + recipientGasLimit: input.recipientGasLimit, + fallbackRecipient: input.fallbackRecipient + }) + ) + }); + + // Send message to the token TokenHome instance. + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: $._tokenHomeBlockchainID, + destinationAddress: $._tokenHomeAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensAndCallSent(messageID, _msgSender(), input, amount); + } + + /** + * @dev Sends tokens to the specified recipient contract on the destination blockchain ID by + * calling the {receiveTokens} method of the respective recipient. + */ + function _processSendAndCallMultiHop(SendAndCallInput calldata input, uint256 amount) private { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + _validateMultiHopInput( + input.destinationBlockchainID, + input.destinationTokenTransferrerAddress, + input.multiHopFallback + ); + + uint256 primaryFee; + (amount, primaryFee) = _prepareSend({ + amount: amount, + primaryFeeTokenAddress: input.primaryFeeTokenAddress, + primaryFee: input.primaryFee, + secondaryFee: input.secondaryFee + }); + + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.MULTI_HOP_CALL, + payload: abi.encode( + MultiHopCallMessage({ + originSenderAddress: _msgSender(), + destinationBlockchainID: input.destinationBlockchainID, + destinationTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + recipientContract: input.recipientContract, + amount: amount, + recipientPayload: input.recipientPayload, + recipientGasLimit: input.recipientGasLimit, + fallbackRecipient: input.fallbackRecipient, + multiHopFallback: input.multiHopFallback, + secondaryRequiredGasLimit: input.requiredGasLimit, + secondaryFee: input.secondaryFee + }) + ) + }); + + // The required gas limit for the first message sent back to the TokenHome instance + // needs to account for the number of words in the payload. Each word uses additional + // gas to include in the message to the final destination chain. + uint256 messageRequiredGasLimit = MULTI_HOP_CALL_REQUIRED_GAS + + (calculateNumWords(input.recipientPayload.length) * MULTI_HOP_CALL_GAS_PER_WORD); + + // Send message to the token TokenHome instance + bytes32 messageID = _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: $._tokenHomeBlockchainID, + destinationAddress: $._tokenHomeAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: input.primaryFeeTokenAddress, + amount: primaryFee + }), + requiredGasLimit: messageRequiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + + emit TokensAndCallSent(messageID, _msgSender(), input, amount); + } + + function _validateSingleHopInput( + address destinationTokenTransferrerAddress, + uint256 secondaryFee, + address multiHopFallback + ) private view { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + require( + destinationTokenTransferrerAddress == $._tokenHomeAddress, + "TokenRemote: invalid destination token transferrer address" + ); + require(secondaryFee == 0, "TokenRemote: non-zero secondary fee"); + require(multiHopFallback == address(0), "TokenRemote: non-zero multi-hop fallback"); + } + + function _validateMultiHopInput( + bytes32 destinationBlockchainID, + address destinationTokenTransferrerAddress, + address multiHopFallback + ) private view { + TokenRemoteStorage storage $ = _getTokenRemoteStorage(); + // If the destination blockchain ID is this blockchain, the destination + // token transferrer address must be a different contract. This is a multi-hop case to + // a different token transfer contract on this chain. + if (destinationBlockchainID == $._blockchainID) { + require( + destinationTokenTransferrerAddress != address(this), + "TokenRemote: invalid destination token transferrer address" + ); + } + require(multiHopFallback != address(0), "TokenRemote: zero multi-hop fallback"); + } + + function _validateSendTokensInput( + SendTokensInput calldata input + ) private pure { + require(input.recipient != address(0), "TokenRemote: zero recipient address"); + require(input.requiredGasLimit > 0, "TokenRemote: zero required gas limit"); + require( + input.destinationBlockchainID != bytes32(0), + "TokenRemote: zero destination blockchain ID" + ); + require( + input.destinationTokenTransferrerAddress != address(0), + "TokenRemote: zero destination token transferrer address" + ); + } + + function _validateSendAndCallInput( + SendAndCallInput calldata input + ) private pure { + require( + input.destinationBlockchainID != bytes32(0), + "TokenRemote: zero destination blockchain ID" + ); + require( + input.destinationTokenTransferrerAddress != address(0), + "TokenRemote: zero destination token transferrer address" + ); + require( + input.recipientContract != address(0), "TokenRemote: zero recipient contract address" + ); + require(input.requiredGasLimit > 0, "TokenRemote: zero required gas limit"); + require(input.recipientGasLimit > 0, "TokenRemote: zero recipient gas limit"); + require( + input.recipientGasLimit < input.requiredGasLimit, + "TokenRemote: invalid recipient gas limit" + ); + require( + input.fallbackRecipient != address(0), "TokenRemote: zero fallback recipient address" + ); + } +} diff --git a/icm-contracts/contracts/ictt/TokenRemote/interfaces/INativeTokenRemote.sol b/icm-contracts/contracts/ictt/TokenRemote/interfaces/INativeTokenRemote.sol new file mode 100644 index 000000000..726cc153d --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenRemote/interfaces/INativeTokenRemote.sol @@ -0,0 +1,35 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {INativeTokenTransferrer} from "../../interfaces/INativeTokenTransferrer.sol"; +import {ITokenRemote} from "./ITokenRemote.sol"; + +/** + * @dev Interface that describes functionalities for a contract that can mint native tokens when + * paired with a {ITokenHome} contract that will lock tokens on another chain. + */ +interface INativeTokenRemote is ITokenRemote, INativeTokenTransferrer { + /** + * @notice Emitted when reporting burned tx fees to home chain. + */ + event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned); + + /** + * @notice Reports the increase in total burned transaction fees on this chain to its corresponding TokenHome instance. + * @param requiredGasLimit The gas limit required to report the burned transaction fees to the home contract. + */ + function reportBurnedTxFees( + uint256 requiredGasLimit + ) external; + + /** + * @notice Returns a best-estimate (upper bound) of the supply of the native asset + * in circulation on this chain. Does not account for other native asset burn mechanisms, + * which can result in the value returned being greater than true circulating supply. + */ + function totalNativeAssetSupply() external view returns (uint256); +} diff --git a/icm-contracts/contracts/ictt/TokenRemote/interfaces/ITokenRemote.sol b/icm-contracts/contracts/ictt/TokenRemote/interfaces/ITokenRemote.sol new file mode 100644 index 000000000..45b72385d --- /dev/null +++ b/icm-contracts/contracts/ictt/TokenRemote/interfaces/ITokenRemote.sol @@ -0,0 +1,43 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ITokenTransferrer} from "../../interfaces/ITokenTransferrer.sol"; +import {TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; + +/** + * @notice Settings for constructing a {ITokenRemote} contract. + * @param teleporterRegistryAddress The current blockchain ID's Teleporter registry + * address. See here for details: https://github.com/ava-labs/icm-contracts/tree/main/contracts/teleporter/registry. + * @param teleporterManager Address that manages this contract's integration with the + * Teleporter registry and Teleporter versions. + * @param minTeleporterVersion Minimum Teleporter version supported by this contract. + * @param tokenHomeBlockchainID The blockchain ID of the associated TokenHome instance. + * @param tokenHomeAddress The address of the associated token home contract. + * @param tokenHomeDecimals The number of decimal places used by the token home's token. + */ +struct TokenRemoteSettings { + address teleporterRegistryAddress; + address teleporterManager; + uint256 minTeleporterVersion; + bytes32 tokenHomeBlockchainID; + address tokenHomeAddress; + uint8 tokenHomeDecimals; +} + +/** + * @dev Interface for a remote token transfer contract that mints a representation token on its chain, and allows + * for burning that token to redeem the backing asset on the home chain, or transferring to other remotes. + */ +interface ITokenRemote is ITokenTransferrer { + /** + * @notice Sends a Teleporter message to register the TokenRemote instance with its configured home. + * @param feeInfo The optional fee asset and amount for the Teleporter message, for relayer incentivization. + */ + function registerWithHome( + TeleporterFeeInfo calldata feeInfo + ) external; +} diff --git a/icm-contracts/contracts/ictt/WrappedNativeToken.sol b/icm-contracts/contracts/ictt/WrappedNativeToken.sol new file mode 100644 index 000000000..453136f7d --- /dev/null +++ b/icm-contracts/contracts/ictt/WrappedNativeToken.sol @@ -0,0 +1,39 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IWrappedNativeToken} from "./interfaces/IWrappedNativeToken.sol"; +import {ERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/ERC20.sol"; +import {Address} from "@openzeppelin/contracts@5.0.2/utils/Address.sol"; + +contract WrappedNativeToken is IWrappedNativeToken, ERC20 { + using Address for address payable; + + constructor( + string memory symbol + ) ERC20(string.concat("Wrapped ", symbol), string.concat("W", symbol)) {} + + receive() external payable { + deposit(); + } + + fallback() external payable { + deposit(); + } + + function withdraw( + uint256 amount + ) external { + _burn(_msgSender(), amount); + emit Withdrawal(_msgSender(), amount); + payable(_msgSender()).sendValue(amount); + } + + function deposit() public payable { + _mint(_msgSender(), msg.value); + emit Deposit(_msgSender(), msg.value); + } +} diff --git a/icm-contracts/contracts/ictt/interfaces/IERC20SendAndCallReceiver.sol b/icm-contracts/contracts/ictt/interfaces/IERC20SendAndCallReceiver.sol new file mode 100644 index 000000000..49289b796 --- /dev/null +++ b/icm-contracts/contracts/ictt/interfaces/IERC20SendAndCallReceiver.sol @@ -0,0 +1,30 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * @notice Interface for contracts that are called to receive token transfers. + */ +interface IERC20SendAndCallReceiver { + /** + * @notice Called to receive the amount of the given token + * @param sourceBlockchainID Blockchain ID that the transfer originated from + * @param originTokenTransferrerAddress Address of the token transferrer that initiated the Teleporter message + * @param originSenderAddress Address of the sender that sent the transfer. This value + * should only be trusted if {originTokenTransferrerAddress} is verified and known. + * @param token Address of the token to be received + * @param amount Amount of the token to be received + * @param payload Arbitrary data provided by the caller + */ + function receiveTokens( + bytes32 sourceBlockchainID, + address originTokenTransferrerAddress, + address originSenderAddress, + address token, + uint256 amount, + bytes calldata payload + ) external; +} diff --git a/icm-contracts/contracts/ictt/interfaces/IERC20TokenTransferrer.sol b/icm-contracts/contracts/ictt/interfaces/IERC20TokenTransferrer.sol new file mode 100644 index 000000000..a92deaa8c --- /dev/null +++ b/icm-contracts/contracts/ictt/interfaces/IERC20TokenTransferrer.sol @@ -0,0 +1,29 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ITokenTransferrer, SendTokensInput, SendAndCallInput} from "./ITokenTransferrer.sol"; + +/** + * @notice Interface for an Avalanche interchain token transferrer that sends ERC20 tokens to another chain. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface IERC20TokenTransferrer is ITokenTransferrer { + /** + * @notice Sends ERC20 tokens to the specified destination. + * @param input Specifies information for delivery of the tokens + * @param amount Amount of tokens to send + */ + function send(SendTokensInput calldata input, uint256 amount) external; + + /** + * @notice Sends ERC20 tokens to the specified destination to be used in a smart contract interaction. + * @param input Specifies information for delivery of the tokens + * @param amount Amount of tokens to send + */ + function sendAndCall(SendAndCallInput calldata input, uint256 amount) external; +} diff --git a/icm-contracts/contracts/ictt/interfaces/INativeSendAndCallReceiver.sol b/icm-contracts/contracts/ictt/interfaces/INativeSendAndCallReceiver.sol new file mode 100644 index 000000000..d07767139 --- /dev/null +++ b/icm-contracts/contracts/ictt/interfaces/INativeSendAndCallReceiver.sol @@ -0,0 +1,28 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * @notice Interface for a contracts that are called to receive native tokens. + */ +interface INativeSendAndCallReceiver { + /** + * @notice Called to receive the amount of the native token. Implementations + * must properly handle the msg.value of the call in order to ensure it doesn't + * become improperly made inaccessible. + * @param sourceBlockchainID Blockchain ID that the transfer originated from + * @param originTokenTransferrerAddress Address of the token transferrer that initiated the Teleporter message + * @param originSenderAddress Address of the sender that sent the transfer. This value + * should only be trusted if {originTokenTransferrerAddress} is verified and known. + * @param payload Arbitrary data provided by the caller + */ + function receiveTokens( + bytes32 sourceBlockchainID, + address originTokenTransferrerAddress, + address originSenderAddress, + bytes calldata payload + ) external payable; +} diff --git a/icm-contracts/contracts/ictt/interfaces/INativeTokenTransferrer.sol b/icm-contracts/contracts/ictt/interfaces/INativeTokenTransferrer.sol new file mode 100644 index 000000000..234a5daaa --- /dev/null +++ b/icm-contracts/contracts/ictt/interfaces/INativeTokenTransferrer.sol @@ -0,0 +1,32 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ITokenTransferrer, SendTokensInput, SendAndCallInput} from "./ITokenTransferrer.sol"; + +/** + * @notice Interface for an Avalanche interchain token transferrer that sends native tokens to another chain. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface INativeTokenTransferrer is ITokenTransferrer { + /** + * @notice Sends native tokens to the specified destination. + * @param input Specifies information for delivery of the tokens + */ + function send( + SendTokensInput calldata input + ) external payable; + + /** + * @notice Sends native tokens to the specified destination to be used in a smart contract interaction. + * @param input Specifies information for delivery of the tokens to the remote contract and contract to be called + * on the remote chain. + */ + function sendAndCall( + SendAndCallInput calldata input + ) external payable; +} diff --git a/icm-contracts/contracts/ictt/interfaces/ITokenTransferrer.sol b/icm-contracts/contracts/ictt/interfaces/ITokenTransferrer.sol new file mode 100644 index 000000000..ddba1a4eb --- /dev/null +++ b/icm-contracts/contracts/ictt/interfaces/ITokenTransferrer.sol @@ -0,0 +1,206 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ITeleporterReceiver} from "@teleporter/ITeleporterReceiver.sol"; + +enum TransferrerMessageType { + REGISTER_REMOTE, + SINGLE_HOP_SEND, + SINGLE_HOP_CALL, + MULTI_HOP_SEND, + MULTI_HOP_CALL +} + +/** + * @notice Input parameters for transferring tokens to another chain as part of a simple transfer. + * @param destinationBlockchainID Blockchain ID of the destination + * @param destinationTokenTransferrerAddress Address of the destination token transferrer instance + * @param recipient Address of the recipient on the destination chain + * @param primaryFeeTokenAddress Address of the ERC20 contract to optionally pay a Teleporter message fee + * @param primaryFee Amount of tokens to pay as the optional Teleporter message fee + * @param secondaryFee Amount of tokens to pay for Teleporter fee if a multi-hop is needed + * @param requiredGasLimit Gas limit requirement for sending to a token transferrer. + * This is required because the gas requirement varies based on the token transferrer instance + * specified by {destinationBlockchainID} and {destinationTokenTransferrerAddress}. + * @param multiHopFallback In the case of a multi-hop transfer, the address where the tokens + * are sent on the home chain if the transfer is unable to be routed to its final destination. + * Note that this address must be able to receive the tokens held as collateral in the home contract. + */ +struct SendTokensInput { + bytes32 destinationBlockchainID; + address destinationTokenTransferrerAddress; + address recipient; + address primaryFeeTokenAddress; + uint256 primaryFee; + uint256 secondaryFee; + uint256 requiredGasLimit; + address multiHopFallback; +} + +/** + * @notice Input parameters for transferring tokens to another chain as part of a transfer with a contract call. + * @param destinationBlockchainID BlockchainID of the destination + * @param destinationTokenTransferrerAddress Address of the destination token transferrer instance + * @param recipientContract The contract on the destination chain that will be called + * @param recipientPayload The payload that will be provided to the recipient contract on the destination chain + * @param requiredGasLimit The required amount of gas needed to deliver the message on its destination chain, + * including token operations and the call to the recipient contract. + * @param recipientGasLimit The amount of gas that will provided to the recipient contract on the destination chain, + * which must be less than the requiredGasLimit of the message as a whole. + * @param multiHopFallback In the case of a multi-hop transfer, the address where the tokens + * are sent on the home chain if the transfer is unable to be routed to its final destination. + * Note that this address must be able to receive the tokens held as collateral in the home contract. + * @param fallbackRecipient Address on the {destinationBlockchainID} where the transferred tokens are sent to if the call + * to the recipient contract fails. Note that this address must be able to receive the tokens on the destination + * chain of the transfer. + * @param primaryFeeTokenAddress Address of the ERC20 contract to optionally pay a Teleporter message fee + * @param primaryFee Amount of tokens to pay for Teleporter fee on the chain that iniiated the transfer + * @param secondaryFee Amount of tokens to pay for Teleporter fee if a multi-hop is needed + */ +struct SendAndCallInput { + bytes32 destinationBlockchainID; + address destinationTokenTransferrerAddress; + address recipientContract; + bytes recipientPayload; + uint256 requiredGasLimit; + uint256 recipientGasLimit; + address multiHopFallback; + address fallbackRecipient; + address primaryFeeTokenAddress; + uint256 primaryFee; + uint256 secondaryFee; +} + +/** + * @dev The TransferrerMessage struct is used to wrap messages between two token transferrer contracts + * with their message type so that the receiving token transferrer can decode the payload. + */ +struct TransferrerMessage { + TransferrerMessageType messageType; + bytes payload; +} + +/** + * @dev Register remote message payloads are sent to the home token transferrer contract to register a new remote contract + * instance on another chain. + * @param initialReserveImbalance The initial reserve imbalance of the remote contract to calculate + * associated collateral needed on home contract. + * @param homeTokenDecimals The number of decimals that the home token has. + * @param remoteTokenDecimals The number of decimals that the remote token has. + */ +struct RegisterRemoteMessage { + uint256 initialReserveImbalance; + uint8 homeTokenDecimals; + uint8 remoteTokenDecimals; +} + +/** + * @dev Single hop send message payloads include the recipient address and transferred amount. + * The destination chain and token transferrer address for the transfer are defined by the Teleporter message. + */ +struct SingleHopSendMessage { + address recipient; + uint256 amount; +} + +/** + * @dev Single hop call message payloads include the required information to call + * the target contract on the destination chain. The destination chain and token transferrer + * address are defined by the Teleporter message. The message also includes the + * blockchain ID and address of the original sender. + */ +struct SingleHopCallMessage { + bytes32 sourceBlockchainID; + address originTokenTransferrerAddress; + address originSenderAddress; + address recipientContract; + uint256 amount; + bytes recipientPayload; + uint256 recipientGasLimit; + address fallbackRecipient; +} + +/** + * @dev Multi hop send message payloads include the recipient address as well as all + * the information the intermediate (home) chain token transferrer contract needs to route + * the send message on to its final destination. + */ +struct MultiHopSendMessage { + bytes32 destinationBlockchainID; + address destinationTokenTransferrerAddress; + address recipient; + uint256 amount; + uint256 secondaryFee; + uint256 secondaryGasLimit; + address multiHopFallback; +} + +/** + * @dev Multi hop call message payloads include the required information to call the target contract on the + * destination chain, as well as the information the intermediate (home) chain token transferrer contract needs to route + * the call message on to its final destination. This includes the {secondaryRequiredGasLimit}, which is the + * required gas limit set for the second Teleporter message. The {secondaryRequiredGasLimit} should be sufficient + * to cover the destination token operations as well as the call to the recipient contract, and will always be + * greater than the recipientGasLimit. The multi-hop message also includes the address of the original sender. + * The source blockchain ID of the sender is known from the Teleporter message. + */ +struct MultiHopCallMessage { + address originSenderAddress; + bytes32 destinationBlockchainID; + address destinationTokenTransferrerAddress; + address recipientContract; + uint256 amount; + bytes recipientPayload; + uint256 recipientGasLimit; + address fallbackRecipient; + uint256 secondaryRequiredGasLimit; + address multiHopFallback; + uint256 secondaryFee; +} + +/** + * @notice Interface for an Avalanche interchain token transferrer that sends tokens to another chain. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface ITokenTransferrer is ITeleporterReceiver { + /** + * @notice Emitted when tokens are sent to another chain. + */ + event TokensSent( + bytes32 indexed teleporterMessageID, + address indexed sender, + SendTokensInput input, + uint256 amount + ); + + /** + * @notice Emitted when tokens are sent to another chain with calldata for a contract recipient. + */ + event TokensAndCallSent( + bytes32 indexed teleporterMessageID, + address indexed sender, + SendAndCallInput input, + uint256 amount + ); + + /** + * @notice Emitted when tokens are withdrawn from the token transferrer contract. + */ + event TokensWithdrawn(address indexed recipient, uint256 amount); + + /** + * @notice Emitted when a call to a recipient contract to receive token succeeds. + */ + event CallSucceeded(address indexed recipientContract, uint256 amount); + + /** + * @notice Emitted when a call to a recipient contract to receive token fails, and the tokens are sent + * to a fallback recipient. + */ + event CallFailed(address indexed recipientContract, uint256 amount); +} diff --git a/icm-contracts/contracts/ictt/interfaces/IWrappedNativeToken.sol b/icm-contracts/contracts/ictt/interfaces/IWrappedNativeToken.sol new file mode 100644 index 000000000..d5662e2bf --- /dev/null +++ b/icm-contracts/contracts/ictt/interfaces/IWrappedNativeToken.sol @@ -0,0 +1,44 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; + +/** + * @title IWrappedNativeToken + * @notice Interface for a wrapped native token + * @dev Implements the {IERC20} interface, and adds deposit and withdraw functions. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface IWrappedNativeToken is IERC20 { + /** + * @notice Emitted when native tokens are deposited. + * @param sender Address that deposited the native tokens + * @param amount Amount of native tokens deposited + */ + event Deposit(address indexed sender, uint256 amount); + + /** + * @notice Emitted when wrapped tokens are withdrawn for native tokens. + * @param sender Address that withdrew the native tokens. + * @param amount Amount of native tokens withdrawn + */ + event Withdrawal(address indexed sender, uint256 amount); + + /** + * @notice Deposits native tokens to receive wrapped tokens. + */ + function deposit() external payable; + + /** + * @notice Withdraws native tokens for wrapped tokens. + * @param amount Amount of native tokens to withdraw + */ + function withdraw( + uint256 amount + ) external; +} diff --git a/icm-contracts/contracts/ictt/mocks/ExampleERC20Decimals.sol b/icm-contracts/contracts/ictt/mocks/ExampleERC20Decimals.sol new file mode 100644 index 000000000..81f9d0c92 --- /dev/null +++ b/icm-contracts/contracts/ictt/mocks/ExampleERC20Decimals.sol @@ -0,0 +1,26 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + * DO NOT USE THIS CODE IN PRODUCTION. + */ +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; + +contract ExampleERC20Decimals is ExampleERC20 { + uint8 public immutable tokenDecimals; + + constructor( + uint8 tokenDecimals_ + ) ExampleERC20() { + tokenDecimals = tokenDecimals_; + } + + function decimals() public view virtual override returns (uint8) { + return tokenDecimals; + } +} diff --git a/icm-contracts/contracts/ictt/mocks/MockERC20SendAndCallReceiver.sol b/icm-contracts/contracts/ictt/mocks/MockERC20SendAndCallReceiver.sol new file mode 100644 index 000000000..3517d73e2 --- /dev/null +++ b/icm-contracts/contracts/ictt/mocks/MockERC20SendAndCallReceiver.sol @@ -0,0 +1,79 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IERC20SendAndCallReceiver} from "../interfaces/IERC20SendAndCallReceiver.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {Context} from "@openzeppelin/contracts@5.0.2/utils/Context.sol"; + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + * DO NOT USE THIS CODE IN PRODUCTION. + */ + +/** + * @notice This is mock implementation of {receiveTokens} to be used in tests. + * This contract DOES NOT provide a mechanism for accessing the tokens transfered to it. + * Real implementations must ensure that tokens are properly handled and not incorrectly locked. + */ +contract MockERC20SendAndCallReceiver is Context, IERC20SendAndCallReceiver { + using SafeERC20 for IERC20; + + mapping(bytes32 blockchainID => mapping(address senderAddress => bool blocked)) public + blockedSenders; + + /** + * @dev Emitted when receiveTokens is called. + */ + event TokensReceived( + bytes32 indexed sourceBlockchainID, + address indexed originTokenTransferrerAddress, + address indexed originSenderAddress, + address token, + uint256 amount, + bytes payload + ); + + /** + * @dev See {IERC20SendAndCallReceiver-receiveTokens} + */ + function receiveTokens( + bytes32 sourceBlockchainID, + address originTokenTransferrerAddress, + address originSenderAddress, + address token, + uint256 amount, + bytes calldata payload + ) external { + require( + !blockedSenders[sourceBlockchainID][originSenderAddress], + "MockERC20SendAndCallReceiver: sender blocked" + ); + emit TokensReceived({ + sourceBlockchainID: sourceBlockchainID, + originTokenTransferrerAddress: originTokenTransferrerAddress, + originSenderAddress: originSenderAddress, + token: token, + amount: amount, + payload: payload + }); + + require(payload.length > 0, "MockERC20SendAndCallReceiver: empty payload"); + + SafeERC20TransferFrom.safeTransferFrom(IERC20(token), _msgSender(), amount); + } + + /** + * @notice Block a sender from sending tokens to this contract. + * @param blockchainID The blockchain ID of the sender. + * @param senderAddress The address of the sender. + */ + function blockSender(bytes32 blockchainID, address senderAddress) external { + blockedSenders[blockchainID][senderAddress] = true; + } +} diff --git a/icm-contracts/contracts/ictt/mocks/MockNativeSendAndCallReceiver.sol b/icm-contracts/contracts/ictt/mocks/MockNativeSendAndCallReceiver.sol new file mode 100644 index 000000000..3cb792add --- /dev/null +++ b/icm-contracts/contracts/ictt/mocks/MockNativeSendAndCallReceiver.sol @@ -0,0 +1,68 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {INativeSendAndCallReceiver} from "../interfaces/INativeSendAndCallReceiver.sol"; + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + * DO NOT USE THIS CODE IN PRODUCTION. + */ + +/** + * @notice This is mock implementation of {receiveTokens} to be used in tests. + * This contract DOES NOT provide a mechanism for accessing the tokens transfered to it. + * Real implementations must ensure that tokens are properly handled and not incorrectly locked. + */ +contract MockNativeSendAndCallReceiver is INativeSendAndCallReceiver { + mapping(bytes32 blockchainID => mapping(address senderAddress => bool blocked)) public + blockedSenders; + + /** + * @dev Emitted when receiveTokens is called. + */ + event TokensReceived( + bytes32 indexed sourceBlockchainID, + address indexed originTokenTransferrerAddress, + address indexed originSenderAddress, + uint256 amount, + bytes payload + ); + + /** + * @dev See {INativeSendAndCallReceiver-receiveTokens} + */ + function receiveTokens( + bytes32 sourceBlockchainID, + address originTokenTransferrerAddress, + address originSenderAddress, + bytes calldata payload + ) external payable { + require( + !blockedSenders[sourceBlockchainID][originSenderAddress], + "MockNativeSendAndCallReceiver: sender blocked" + ); + emit TokensReceived( + sourceBlockchainID, + originTokenTransferrerAddress, + originSenderAddress, + msg.value, + payload + ); + + require(payload.length != 0, "MockNativeSendAndCallReceiver: empty payload"); + // No implementation required to accept native tokens + } + + /** + * @notice Block a sender from sending tokens to this contract. + * @param blockchainID The blockchain ID of the sender. + * @param senderAddress The address of the sender. + */ + function blockSender(bytes32 blockchainID, address senderAddress) external { + blockedSenders[blockchainID][senderAddress] = true; + } +} diff --git a/icm-contracts/contracts/ictt/tests/ERC20TokenHomeTests.t.sol b/icm-contracts/contracts/ictt/tests/ERC20TokenHomeTests.t.sol new file mode 100644 index 000000000..8f0f26bbf --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/ERC20TokenHomeTests.t.sol @@ -0,0 +1,320 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ERC20TokenTransferrerTest} from "./ERC20TokenTransferrerTests.t.sol"; +import {TokenHomeTest} from "./TokenHomeTests.t.sol"; +import {IERC20SendAndCallReceiver} from "../interfaces/IERC20SendAndCallReceiver.sol"; +import {SendTokensInput} from "../interfaces/ITokenTransferrer.sol"; +import {ERC20TokenHomeUpgradeable} from "../TokenHome/ERC20TokenHomeUpgradeable.sol"; +import {ERC20TokenHome} from "../TokenHome/ERC20TokenHome.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {TeleporterMessageInput, TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; +import {TokenScalingUtils} from "@utilities/TokenScalingUtils.sol"; +import {RemoteTokenTransferrerSettings} from "../TokenHome/interfaces/ITokenHome.sol"; +import {Ownable} from "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; + +contract ERC20TokenHomeTest is ERC20TokenTransferrerTest, TokenHomeTest { + using SafeERC20 for IERC20; + + ERC20TokenHomeUpgradeable public app; + IERC20 public mockERC20; + + function setUp() public override { + TokenHomeTest.setUp(); + + mockERC20 = new ExampleERC20(); + tokenHomeDecimals = 6; + app = new ERC20TokenHomeUpgradeable(ICMInitializable.Allowed); + app.initialize( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + MOCK_TELEPORTER_MESSENGER_ADDRESS, + 1, + address(mockERC20), + tokenHomeDecimals + ); + erc20TokenTransferrer = app; + tokenHome = app; + tokenTransferrer = app; + + transferredToken = mockERC20; + } + + /** + * Initialization unit tests + */ + function testNonUpgradeableInitialization() public { + app = new ERC20TokenHome( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + address(this), + 1, + address(mockERC20), + tokenHomeDecimals + ); + assertEq(app.getBlockchainID(), DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID); + } + + function testDisableInitialization() public { + app = new ERC20TokenHomeUpgradeable(ICMInitializable.Disallowed); + vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + app.initialize( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + address(this), + 1, + address(mockERC20), + tokenHomeDecimals + ); + } + + function testZeroTeleporterRegistryAddress() public { + _invalidInitialization( + address(0), + address(this), + address(mockERC20), + tokenHomeDecimals, + "TeleporterRegistryApp: zero Teleporter registry address" + ); + } + + function testZeroTeleporterManagerAddress() public { + _invalidInitialization( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + address(0), + address(mockERC20), + tokenHomeDecimals, + abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0)) + ); + } + + function testZeroFeeTokenAddress() public { + _invalidInitialization( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + address(this), + address(0), + tokenHomeDecimals, + _formatErrorMessage("zero token address") + ); + } + + function testTokenDecimalsTooHigh() public { + _invalidInitialization( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + address(this), + address(mockERC20), + uint8(TokenScalingUtils.MAX_TOKEN_DECIMALS) + 1, + _formatErrorMessage("token decimals too high") + ); + } + + function testReceiveZeroHomeTokenAmount() public { + // Set up a registered remote that will scale down the received amount + // to zero home tokens. + uint256 tokenMultiplier = 100_000; + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + 0, + tokenMultiplier, + true + ); + + // Send over home token to the remote + // and check for expected calls for scaled amount of tokens sent. + SendTokensInput memory input = _createDefaultSendTokensInput(); + uint256 amount = 1; + _setUpExpectedDeposit(amount, input.primaryFee); + + uint256 scaledAmount = tokenMultiplier * amount; + _checkExpectedTeleporterCallsForSend( + _createSingleHopTeleporterMessageInput(input, scaledAmount) + ); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensSent(_MOCK_MESSAGE_ID, address(this), input, scaledAmount); + _send(input, amount); + + // Receive an amount from remote less than `scaledAmount` + // which will be scaled down to zero home tokens. + vm.expectRevert(_formatErrorMessage("zero token amount")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeSingleHopSendMessage(scaledAmount - 1, DEFAULT_RECIPIENT_ADDRESS) + ); + } + + function testRegisterDestinationRoundUpCollateralNeeded() public { + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 11, 10, true + ); + RemoteTokenTransferrerSettings memory settings = tokenHome.getRemoteTokenTransferrerSettings( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS + ); + assertEq(settings.collateralNeeded, 2); + } + + function testSendScaledUpAmount() public { + uint256 amount = 100; + uint256 feeAmount = 1; + + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.primaryFee = feeAmount; + + // Raw amount sent over wire should be multipled by 1e2. + uint256 tokenMultiplier = 1e2; + _setUpRegisteredRemote( + input.destinationBlockchainID, + input.destinationTokenTransferrerAddress, + 0, + tokenMultiplier, + true + ); + _setUpExpectedDeposit(amount, input.primaryFee); + TeleporterMessageInput memory expectedMessage = TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(transferredToken), + amount: input.primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: _encodeSingleHopSendMessage(amount * tokenMultiplier, DEFAULT_RECIPIENT_ADDRESS) + }); + _checkExpectedTeleporterCallsForSend(expectedMessage); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensSent(_MOCK_MESSAGE_ID, address(this), input, amount * tokenMultiplier); + _send(input, amount); + } + + function _checkExpectedWithdrawal(address recipient, uint256 amount) internal override { + vm.expectEmit(true, true, true, true, address(tokenHome)); + emit TokensWithdrawn(recipient, amount); + vm.expectCall( + address(mockERC20), abi.encodeCall(IERC20.transfer, (address(recipient), amount)) + ); + vm.expectEmit(true, true, true, true, address(mockERC20)); + emit Transfer(address(app), recipient, amount); + } + + function _setUpExpectedSendAndCall( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + address recipient, + uint256 amount, + bytes memory payload, + uint256 gasLimit, + bool targetHasCode, + bool expectSuccess + ) internal override { + // The recipient contract will be approved to spend the tokens from the token home contract. + vm.expectEmit(true, true, true, true, address(mockERC20)); + emit Approval(address(app), DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + + if (targetHasCode) { + vm.etch(recipient, new bytes(1)); + + bytes memory expectedCalldata = abi.encodeCall( + IERC20SendAndCallReceiver.receiveTokens, + ( + sourceBlockchainID, + originInfo.tokenTransferrerAddress, + originInfo.senderAddress, + address(mockERC20), + amount, + payload + ) + ); + if (expectSuccess) { + vm.mockCall(recipient, expectedCalldata, new bytes(0)); + } else { + vm.mockCallRevert(recipient, expectedCalldata, new bytes(0)); + } + vm.expectCall(recipient, 0, uint64(gasLimit), expectedCalldata); + } else { + vm.etch(recipient, new bytes(0)); + } + + // Then recipient contract approval is reset + vm.expectEmit(true, true, true, true, address(mockERC20)); + emit Approval(address(app), DEFAULT_RECIPIENT_CONTRACT_ADDRESS, 0); + + if (targetHasCode && expectSuccess) { + // The call should have succeeded. + vm.expectEmit(true, true, true, true, address(app)); + emit CallSucceeded(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + } else { + // The call should have failed. + vm.expectEmit(true, true, true, true, address(app)); + emit CallFailed(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + + // Then the amount should be sent to the fallback recipient. + vm.expectEmit(true, true, true, true, address(mockERC20)); + emit Transfer(address(app), address(DEFAULT_FALLBACK_RECIPIENT_ADDRESS), amount); + } + } + + function _addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) internal override { + app.addCollateral(remoteBlockchainID, remoteTokenTransferrerAddress, amount); + } + + function _setUpDeposit( + uint256 amount + ) internal virtual override { + // Increase the allowance of the token transferrer to transfer the funds from the user + transferredToken.safeIncreaseAllowance(address(tokenTransferrer), amount); + } + + function _setUpExpectedZeroAmountRevert() internal override { + vm.expectRevert("SafeERC20TransferFrom: balance not increased"); + } + + function _setUpExpectedDeposit(uint256 amount, uint256 feeAmount) internal virtual override { + // Transfer the fee to the token transferrer if it is greater than 0 + if (feeAmount > 0) { + transferredToken.safeIncreaseAllowance(address(tokenTransferrer), feeAmount); + vm.expectCall( + address(transferredToken), + abi.encodeCall( + IERC20.transferFrom, (address(this), address(tokenTransferrer), feeAmount) + ) + ); + } + // Increase the allowance of the token transferrer to transfer the funds from the user + transferredToken.safeIncreaseAllowance(address(tokenTransferrer), amount); + + // Check that transferFrom is called to deposit the funds sent from the user to the token transferrer + // This is the case because for the {ERC20TokenHomeUpgradeable) is not the fee token itself + vm.expectCall( + address(transferredToken), + abi.encodeCall(IERC20.transferFrom, (address(this), address(tokenTransferrer), amount)) + ); + vm.expectEmit(true, true, true, true, address(transferredToken)); + emit Transfer(address(this), address(tokenTransferrer), amount); + } + + function _invalidInitialization( + address teleporterRegistryAddress, + address teleporterManagerAddress, + address feeTokenAddress, + uint8 tokenDecimals, + bytes memory expectedErrorMessage + ) private { + app = new ERC20TokenHomeUpgradeable(ICMInitializable.Allowed); + vm.expectRevert(expectedErrorMessage); + app.initialize( + teleporterRegistryAddress, teleporterManagerAddress, 1, feeTokenAddress, tokenDecimals + ); + } +} diff --git a/icm-contracts/contracts/ictt/tests/ERC20TokenRemoteTests.t.sol b/icm-contracts/contracts/ictt/tests/ERC20TokenRemoteTests.t.sol new file mode 100644 index 000000000..e7378531b --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/ERC20TokenRemoteTests.t.sol @@ -0,0 +1,338 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ERC20TokenTransferrerTest} from "./ERC20TokenTransferrerTests.t.sol"; +import {TokenRemoteTest} from "./TokenRemoteTests.t.sol"; +import {IERC20SendAndCallReceiver} from "../interfaces/IERC20SendAndCallReceiver.sol"; +import {TokenRemote} from "../TokenRemote/TokenRemote.sol"; +import {TokenRemoteSettings} from "../TokenRemote/interfaces/ITokenRemote.sol"; +import {ERC20TokenRemoteUpgradeable} from "../TokenRemote/ERC20TokenRemoteUpgradeable.sol"; +import {ERC20TokenRemote} from "../TokenRemote/ERC20TokenRemote.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; +import {SendTokensInput} from "../interfaces/ITokenTransferrer.sol"; +import {Ownable} from "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; + +contract ERC20TokenRemoteTest is ERC20TokenTransferrerTest, TokenRemoteTest { + using SafeERC20 for IERC20; + + string public constant MOCK_TOKEN_NAME = "Test Token"; + string public constant MOCK_TOKEN_SYMBOL = "TST"; + + ERC20TokenRemoteUpgradeable public app; + + function setUp() public virtual override { + TokenRemoteTest.setUp(); + + tokenDecimals = 14; + tokenHomeDecimals = 18; + app = ERC20TokenRemoteUpgradeable(address(_createNewRemoteInstance())); + + erc20TokenTransferrer = app; + tokenRemote = app; + tokenTransferrer = app; + + vm.expectEmit(true, true, true, true, address(app)); + emit Transfer(address(0), address(this), 10e18); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + app.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + DEFAULT_TOKEN_HOME_ADDRESS, + _encodeSingleHopSendMessage(10e18, address(this)) + ); + } + + /** + * Initialization unit tests + */ + function testNonUpgradeableInitialization() public { + app = new ERC20TokenRemote( + TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + tokenDecimals + ); + assertEq(app.getBlockchainID(), DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID); + } + + function testDisableInitialization() public { + app = new ERC20TokenRemoteUpgradeable(ICMInitializable.Disallowed); + vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + app.initialize( + TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + tokenDecimals + ); + } + + function testZeroTeleporterRegistryAddress() public { + _invalidInitialization( + TokenRemoteSettings({ + teleporterRegistryAddress: address(0), + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + tokenDecimals, + "TeleporterRegistryApp: zero Teleporter registry address" + ); + } + + function testZeroTeleporterManagerAddress() public { + _invalidInitialization( + TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(0), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + tokenDecimals, + abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0)) + ); + } + + function testZeroTokenHomeBlockchainID() public { + _invalidInitialization( + TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: bytes32(0), + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + tokenDecimals, + _formatErrorMessage("zero token home blockchain ID") + ); + } + + function testDeployToSameBlockchain() public { + _invalidInitialization( + TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + tokenDecimals, + _formatErrorMessage("cannot deploy to same blockchain as token home") + ); + } + + function testZeroTokenHomeAddress() public { + _invalidInitialization( + TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: address(0), + tokenHomeDecimals: 18 + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + 18, + _formatErrorMessage("zero token home address") + ); + } + + function testSendWithSeparateFeeAsset() public { + uint256 amount = 200_000; + uint256 feeAmount = 100; + ExampleERC20 separateFeeAsset = new ExampleERC20(); + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.primaryFeeTokenAddress = address(separateFeeAsset); + input.primaryFee = feeAmount; + + IERC20(separateFeeAsset).safeIncreaseAllowance(address(tokenTransferrer), feeAmount); + vm.expectCall( + address(separateFeeAsset), + abi.encodeCall( + IERC20.transferFrom, (address(this), address(tokenTransferrer), feeAmount) + ) + ); + // Increase the allowance of the token transferrer to transfer the funds from the user + IERC20(app).safeIncreaseAllowance(address(tokenTransferrer), amount); + + vm.expectEmit(true, true, true, true, address(app)); + emit Transfer(address(this), address(0), amount); + _checkExpectedTeleporterCallsForSend(_createSingleHopTeleporterMessageInput(input, amount)); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensSent(_MOCK_MESSAGE_ID, address(this), input, amount); + _send(input, amount); + } + + function testDecimals() public view { + uint8 res = app.decimals(); + assertEq(tokenDecimals, res); + } + + function _createNewRemoteInstance() internal override returns (TokenRemote) { + ERC20TokenRemoteUpgradeable instance = + new ERC20TokenRemoteUpgradeable(ICMInitializable.Allowed); + instance.initialize( + TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + MOCK_TOKEN_NAME, + MOCK_TOKEN_SYMBOL, + tokenDecimals + ); + return instance; + } + + function _checkExpectedWithdrawal(address recipient, uint256 amount) internal override { + vm.expectEmit(true, true, true, true, address(tokenRemote)); + emit TokensWithdrawn(recipient, amount); + vm.expectEmit(true, true, true, true, address(tokenRemote)); + emit Transfer(address(0), recipient, amount); + } + + function _setUpExpectedSendAndCall( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + address recipient, + uint256 amount, + bytes memory payload, + uint256 gasLimit, + bool targetHasCode, + bool expectSuccess + ) internal override { + // The transferred tokens will be minted to the contract itself + vm.expectEmit(true, true, true, true, address(app)); + emit Transfer(address(0), address(tokenRemote), amount); + + // Then recipient contract is then approved to spend them + vm.expectEmit(true, true, true, true, address(app)); + emit Approval(address(app), DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + + if (targetHasCode) { + vm.etch(recipient, new bytes(1)); + + bytes memory expectedCalldata = abi.encodeCall( + IERC20SendAndCallReceiver.receiveTokens, + ( + sourceBlockchainID, + originInfo.tokenTransferrerAddress, + originInfo.senderAddress, + address(app), + amount, + payload + ) + ); + if (expectSuccess) { + vm.mockCall(recipient, expectedCalldata, new bytes(0)); + } else { + vm.mockCallRevert(recipient, expectedCalldata, new bytes(0)); + } + vm.expectCall(recipient, 0, uint64(gasLimit), expectedCalldata); + } else { + vm.etch(recipient, new bytes(0)); + } + + // Then recipient contract approval is reset + vm.expectEmit(true, true, true, true, address(app)); + emit Approval(address(app), DEFAULT_RECIPIENT_CONTRACT_ADDRESS, 0); + + if (targetHasCode && expectSuccess) { + // The call should have succeeded. + vm.expectEmit(true, true, true, true, address(app)); + emit CallSucceeded(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + } else { + // The call should have failed. + vm.expectEmit(true, true, true, true, address(app)); + emit CallFailed(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + + // Then the amount should be sent to the fallback recipient. + vm.expectEmit(true, true, true, true, address(app)); + emit Transfer(address(app), address(DEFAULT_FALLBACK_RECIPIENT_ADDRESS), amount); + } + } + + function _setUpExpectedZeroAmountRevert() internal override { + vm.expectRevert(_formatErrorMessage("insufficient tokens to transfer")); + } + + function _setUpExpectedDeposit(uint256 amount, uint256 feeAmount) internal virtual override { + // Transfer the fee to the token transferrer if it is greater than 0 + if (feeAmount > 0) { + IERC20(app).safeIncreaseAllowance(address(tokenTransferrer), feeAmount); + } + + // Increase the allowance of the token transferrer to transfer the funds from the user + IERC20(app).safeIncreaseAllowance(address(tokenTransferrer), amount); + + // Account for the burn before sending + vm.expectEmit(true, true, true, true, address(app)); + emit Transfer(address(this), address(0), amount); + + if (feeAmount > 0) { + vm.expectEmit(true, true, true, true, address(app)); + emit Transfer(address(this), address(tokenTransferrer), feeAmount); + } + } + + function _getTotalSupply() internal view override returns (uint256) { + return app.totalSupply(); + } + + function _setUpMockMint(address, uint256) internal pure override { + // Don't need to mock the minting of an ERC20TokenRemoteUpgradeable since it is an internal call + // on the remote contract. + return; + } + + function _invalidInitialization( + TokenRemoteSettings memory settings, + string memory tokenName, + string memory tokenSymbol, + uint8 tokenDecimals_, + bytes memory expectedErrorMessage + ) private { + app = new ERC20TokenRemoteUpgradeable(ICMInitializable.Allowed); + vm.expectRevert(expectedErrorMessage); + app.initialize(settings, tokenName, tokenSymbol, tokenDecimals_); + } +} diff --git a/icm-contracts/contracts/ictt/tests/ERC20TokenTransferrerTests.t.sol b/icm-contracts/contracts/ictt/tests/ERC20TokenTransferrerTests.t.sol new file mode 100644 index 000000000..fe3b136cd --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/ERC20TokenTransferrerTests.t.sol @@ -0,0 +1,70 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenTransferrerTest} from "./TokenTransferrerTests.t.sol"; +import {IERC20TokenTransferrer} from "../interfaces/IERC20TokenTransferrer.sol"; +import {SendTokensInput, SendAndCallInput} from "../interfaces/ITokenTransferrer.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {IERC20Errors} from "@openzeppelin/contracts@5.0.2/interfaces/draft-IERC6093.sol"; + +abstract contract ERC20TokenTransferrerTest is TokenTransferrerTest { + using SafeERC20 for IERC20; + + IERC20TokenTransferrer public erc20TokenTransferrer; + + function testZeroSendAmount() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + _setUpExpectedZeroAmountRevert(); + _send(input, 0); + } + + function testSendNoAllowance() public { + uint256 amount = 2e15; + + SendTokensInput memory input = _createDefaultSendTokensInput(); + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, erc20TokenTransferrer, 0, amount + ) + ); + _send(input, amount); + } + + function testSendAndCallNoAllowance() public { + uint256 amount = 2e15; + + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, erc20TokenTransferrer, 0, amount + ) + ); + _sendAndCall(input, amount); + } + + function _send(SendTokensInput memory input, uint256 amount) internal virtual override { + // solhint-disable-next-line check-send-result + erc20TokenTransferrer.send(input, amount); + } + + function _sendAndCall( + SendAndCallInput memory input, + uint256 amount + ) internal virtual override { + erc20TokenTransferrer.sendAndCall(input, amount); + } +} diff --git a/icm-contracts/contracts/ictt/tests/ExampleERC20DecimalsTests.t.sol b/icm-contracts/contracts/ictt/tests/ExampleERC20DecimalsTests.t.sol new file mode 100644 index 000000000..52b828534 --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/ExampleERC20DecimalsTests.t.sol @@ -0,0 +1,22 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ExampleERC20Decimals} from "../mocks/ExampleERC20Decimals.sol"; + +contract ExampleERC20DecimalsTest is Test { + uint8 public constant MOCK_DECIMALS = 11; + ExampleERC20Decimals public exampleERC20; + + function setUp() public virtual { + exampleERC20 = new ExampleERC20Decimals(MOCK_DECIMALS); + } + + function testDecimals() public view { + assertEq(exampleERC20.decimals(), MOCK_DECIMALS); + } +} diff --git a/icm-contracts/contracts/ictt/tests/MockSendAndCallReceiverTest.t.sol b/icm-contracts/contracts/ictt/tests/MockSendAndCallReceiverTest.t.sol new file mode 100644 index 000000000..db7ca0002 --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/MockSendAndCallReceiverTest.t.sol @@ -0,0 +1,169 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {MockERC20SendAndCallReceiver} from "../mocks/MockERC20SendAndCallReceiver.sol"; +import {MockNativeSendAndCallReceiver} from "../mocks/MockNativeSendAndCallReceiver.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; + +contract MockERC20SendAndCallReceiverTest is Test { + bytes32 public constant DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + + IERC20 public erc20; + MockERC20SendAndCallReceiver public erc20SendAndCallReceiver; + + address internal _originSenderAddress = vm.addr(0x1); + address internal _originTokenTransferrerAddress = vm.addr(0x2); + + event TokensReceived( + bytes32 indexed sourceBlockchainID, + address indexed originTokenTransferrerAddress, + address indexed originSenderAddress, + address token, + uint256 amount, + bytes payload + ); + + function setUp() public virtual { + erc20 = new ExampleERC20(); + erc20SendAndCallReceiver = new MockERC20SendAndCallReceiver(); + } + + function testRevert() public { + vm.expectRevert("MockERC20SendAndCallReceiver: empty payload"); + erc20SendAndCallReceiver.receiveTokens({ + sourceBlockchainID: bytes32(0), + originTokenTransferrerAddress: address(this), + originSenderAddress: address(this), + token: address(erc20), + amount: 10, + payload: new bytes(0) + }); + } + + function testSuccess() public { + uint256 amount = 100; + bytes memory payload = hex"9876543210"; + erc20.approve(address(erc20SendAndCallReceiver), amount); + vm.expectEmit(true, true, true, true, address(erc20SendAndCallReceiver)); + emit TokensReceived({ + sourceBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + originTokenTransferrerAddress: _originTokenTransferrerAddress, + originSenderAddress: _originSenderAddress, + token: address(erc20), + amount: amount, + payload: payload + }); + erc20SendAndCallReceiver.receiveTokens({ + sourceBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + originTokenTransferrerAddress: _originTokenTransferrerAddress, + originSenderAddress: _originSenderAddress, + token: address(erc20), + amount: amount, + payload: payload + }); + assertEq(erc20.balanceOf(address(erc20SendAndCallReceiver)), amount); + } + + function testReceiveSenderCheck() public { + uint256 amount = 100; + bytes memory payload = hex"9876543210"; + erc20.approve(address(erc20SendAndCallReceiver), amount); + + erc20SendAndCallReceiver.blockSender(DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, _originSenderAddress); + assertTrue( + erc20SendAndCallReceiver.blockedSenders( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, _originSenderAddress + ) + ); + + vm.expectRevert("MockERC20SendAndCallReceiver: sender blocked"); + erc20SendAndCallReceiver.receiveTokens({ + sourceBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + originTokenTransferrerAddress: _originTokenTransferrerAddress, + originSenderAddress: _originSenderAddress, + token: address(erc20), + amount: amount, + payload: payload + }); + assertEq(erc20.balanceOf(address(erc20SendAndCallReceiver)), 0); + } +} + +contract MockNativeSendAndCallReceiverTest is Test { + bytes32 public constant DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + + MockNativeSendAndCallReceiver public nativeSendAndCallReceiver; + + address internal _originSenderAddress = vm.addr(0x1); + address internal _originTokenTransferrerAddress = vm.addr(0x2); + + event TokensReceived( + bytes32 indexed sourceBlockchainID, + address indexed originTokenTransferrerAddress, + address indexed originSenderAddress, + uint256 amount, + bytes payload + ); + + function setUp() public virtual { + nativeSendAndCallReceiver = new MockNativeSendAndCallReceiver(); + } + + function testRevert() public { + vm.expectRevert("MockNativeSendAndCallReceiver: empty payload"); + nativeSendAndCallReceiver.receiveTokens( + bytes32(0), address(this), address(this), new bytes(0) + ); + } + + function testSuccess() public { + uint256 amount = 10; + bytes memory payload = hex"1234567890"; + vm.expectEmit(true, true, true, true, address(nativeSendAndCallReceiver)); + emit TokensReceived( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + _originTokenTransferrerAddress, + _originSenderAddress, + amount, + payload + ); + nativeSendAndCallReceiver.receiveTokens{value: amount}( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + _originTokenTransferrerAddress, + _originSenderAddress, + payload + ); + assertEq(address(nativeSendAndCallReceiver).balance, amount); + } + + function testReceiveSenderCheck() public { + uint256 amount = 10; + bytes memory payload = hex"1234567890"; + + nativeSendAndCallReceiver.blockSender( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, _originSenderAddress + ); + assertTrue( + nativeSendAndCallReceiver.blockedSenders( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, _originSenderAddress + ) + ); + + vm.expectRevert("MockNativeSendAndCallReceiver: sender blocked"); + nativeSendAndCallReceiver.receiveTokens{value: amount}( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + _originTokenTransferrerAddress, + _originSenderAddress, + payload + ); + assertEq(address(nativeSendAndCallReceiver).balance, 0); + } +} diff --git a/icm-contracts/contracts/ictt/tests/NativeTokenHomeTests.t.sol b/icm-contracts/contracts/ictt/tests/NativeTokenHomeTests.t.sol new file mode 100644 index 000000000..9d83d5a6b --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/NativeTokenHomeTests.t.sol @@ -0,0 +1,185 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenHomeTest} from "./TokenHomeTests.t.sol"; +import {NativeTokenTransferrerTest} from "./NativeTokenTransferrerTests.t.sol"; +import {NativeTokenHomeUpgradeable} from "../TokenHome/NativeTokenHomeUpgradeable.sol"; +import {NativeTokenHome} from "../TokenHome/NativeTokenHome.sol"; +import {IWrappedNativeToken} from "../interfaces/IWrappedNativeToken.sol"; +import {INativeSendAndCallReceiver} from "../interfaces/INativeSendAndCallReceiver.sol"; +import {WrappedNativeToken} from "../WrappedNativeToken.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {Ownable} from "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; + +contract NativeTokenHomeTest is NativeTokenTransferrerTest, TokenHomeTest { + using SafeERC20 for IERC20; + + NativeTokenHomeUpgradeable public app; + IWrappedNativeToken public wavax; + + receive() external payable { + require(msg.sender == address(app), "NativeTokenHomeTest: invalid receive payable sender"); + } + + function setUp() public override { + TokenHomeTest.setUp(); + + wavax = new WrappedNativeToken("AVAX"); + app = new NativeTokenHomeUpgradeable(ICMInitializable.Allowed); + app.initialize( + MOCK_TELEPORTER_REGISTRY_ADDRESS, MOCK_TELEPORTER_MESSENGER_ADDRESS, 1, address(wavax) + ); + tokenHome = app; + nativeTokenTransferrer = app; + tokenTransferrer = app; + transferredToken = IERC20(wavax); + tokenHomeDecimals = 18; + } + + /** + * Initialization unit tests + */ + function testNonUpgradeableInitialization() public { + app = + new NativeTokenHome(MOCK_TELEPORTER_REGISTRY_ADDRESS, address(this), 1, address(wavax)); + assertEq(app.getBlockchainID(), DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID); + } + + function testDisableInitialization() public { + app = new NativeTokenHomeUpgradeable(ICMInitializable.Disallowed); + vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + app.initialize(MOCK_TELEPORTER_REGISTRY_ADDRESS, address(this), 1, address(wavax)); + } + + function testZeroTeleporterRegistryAddress() public { + _invalidInitialization( + address(0), + address(this), + address(wavax), + "TeleporterRegistryApp: zero Teleporter registry address" + ); + } + + function testZeroTeleporterManagerAddress() public { + _invalidInitialization( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + address(0), + address(wavax), + abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0)) + ); + } + + function testZeroFeeTokenAddress() public { + _invalidInitialization( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + address(this), + address(0), + _formatErrorMessage("zero token address") + ); + } + + function _checkExpectedWithdrawal(address recipient, uint256 amount) internal override { + vm.expectEmit(true, true, true, true, address(tokenHome)); + emit TokensWithdrawn(recipient, amount); + vm.expectCall(address(wavax), abi.encodeCall(IWrappedNativeToken.withdraw, (amount))); + vm.expectEmit(true, true, true, true, address(wavax)); + emit Withdrawal(address(app), amount); + } + + function _setUpExpectedSendAndCall( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + address recipient, + uint256 amount, + bytes memory payload, + uint256 gasLimit, + bool targetHasCode, + bool expectSuccess + ) internal override { + if (targetHasCode) { + // Non-zero code length + vm.etch(recipient, new bytes(1)); + + bytes memory expectedCalldata = abi.encodeCall( + INativeSendAndCallReceiver.receiveTokens, + ( + sourceBlockchainID, + originInfo.tokenTransferrerAddress, + originInfo.senderAddress, + payload + ) + ); + if (expectSuccess) { + vm.mockCall(recipient, amount, expectedCalldata, new bytes(0)); + } else { + vm.mockCallRevert(recipient, amount, expectedCalldata, new bytes(0)); + } + vm.expectCall(recipient, amount, uint64(gasLimit), expectedCalldata); + } else { + // No code at target + vm.etch(recipient, new bytes(0)); + } + + if (targetHasCode && expectSuccess) { + vm.expectEmit(true, true, true, true, address(app)); + emit CallSucceeded(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + } else { + vm.expectEmit(true, true, true, true, address(app)); + emit CallFailed(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + } + } + + function _setUpExpectedDeposit(uint256 amount, uint256 feeAmount) internal override { + wavax.deposit{value: feeAmount}(); + // Transfer the fee to the token transferrer if it is greater than 0 + if (feeAmount > 0) { + transferredToken.safeIncreaseAllowance(address(tokenTransferrer), feeAmount); + vm.expectCall( + address(transferredToken), + abi.encodeCall( + IERC20.transferFrom, (address(this), address(tokenTransferrer), feeAmount) + ) + ); + } + + vm.expectCall(address(transferredToken), abi.encodeCall(IWrappedNativeToken.deposit, ())); + vm.expectEmit(true, true, true, true, address(transferredToken)); + emit Deposit(address(nativeTokenTransferrer), amount); + } + + function _setUpDeposit( + uint256 amount + ) internal virtual override + // solhint-disable-next-line no-empty-blocks + {} + + function _setUpExpectedZeroAmountRevert() internal override { + vm.expectRevert("SafeWrappedNativeTokenDeposit: balance not increased"); + } + + function _addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) internal override { + app.addCollateral{value: amount}(remoteBlockchainID, remoteTokenTransferrerAddress); + } + + function _invalidInitialization( + address teleporterRegistryAddress, + address teleporterManagerAddress, + address wrappedTokenAddress, + bytes memory expectedErrorMessage + ) private { + app = new NativeTokenHomeUpgradeable(ICMInitializable.Allowed); + vm.expectRevert(expectedErrorMessage); + app.initialize(teleporterRegistryAddress, teleporterManagerAddress, 1, wrappedTokenAddress); + } +} diff --git a/icm-contracts/contracts/ictt/tests/NativeTokenRemoteTests.t.sol b/icm-contracts/contracts/ictt/tests/NativeTokenRemoteTests.t.sol new file mode 100644 index 000000000..7c7c503fb --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/NativeTokenRemoteTests.t.sol @@ -0,0 +1,558 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenRemoteTest} from "./TokenRemoteTests.t.sol"; +import {NativeTokenTransferrerTest} from "./NativeTokenTransferrerTests.t.sol"; +import {INativeSendAndCallReceiver} from "../interfaces/INativeSendAndCallReceiver.sol"; +import {TokenRemote} from "../TokenRemote/TokenRemote.sol"; +import {NativeTokenRemoteUpgradeable} from "../TokenRemote/NativeTokenRemoteUpgradeable.sol"; +import {NativeTokenRemote} from "../TokenRemote/NativeTokenRemote.sol"; +import {TokenRemoteSettings} from "../TokenRemote/interfaces/ITokenRemote.sol"; +import {INativeMinter} from "@subnet-evm/INativeMinter.sol"; +import { + ITeleporterMessenger, + TeleporterMessageInput, + TeleporterFeeInfo +} from "@teleporter/ITeleporterMessenger.sol"; +import {SendTokensInput} from "../interfaces/ITokenTransferrer.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; + +contract NativeTokenRemoteTest is NativeTokenTransferrerTest, TokenRemoteTest { + using SafeERC20 for IERC20; + + address public constant TEST_ACCOUNT = 0xd4E96eF8eee8678dBFf4d535E033Ed1a4F7605b7; + string public constant DEFAULT_SYMBOL = "XYZ"; + NativeTokenRemoteUpgradeable public app; + + event ReportBurnedTxFees(bytes32 indexed teleporterMessageID, uint256 feesBurned); + + function setUp() public override { + TokenRemoteTest.setUp(); + + tokenHomeDecimals = 6; + app = NativeTokenRemoteUpgradeable(payable(address(_createNewRemoteInstance()))); + tokenRemote = app; + nativeTokenTransferrer = app; + tokenTransferrer = app; + assertEq(app.totalNativeAssetSupply(), _DEFAULT_INITIAL_RESERVE_IMBALANCE); + _collateralizeTokenTransferrer(); + } + + /** + * Initialization unit tests + */ + function testNonUpgradeableInitialization() public { + app = new NativeTokenRemote({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + burnedFeesReportingRewardPercentage: _DEFAULT_BURN_FEE_REWARDS_PERCENTAGE + }); + assertEq(app.getBlockchainID(), DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID); + } + + function testDisableInitialization() public { + app = new NativeTokenRemoteUpgradeable(ICMInitializable.Disallowed); + vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + app.initialize({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + burnedFeesReportingRewardPercentage: _DEFAULT_BURN_FEE_REWARDS_PERCENTAGE + }); + } + + function testZeroInitialReserveImbalance() public { + _invalidInitialization({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: 0, + burnedFeesReportingRewardPercentage: _DEFAULT_BURN_FEE_REWARDS_PERCENTAGE, + expectedErrorMessage: "NativeTokenRemote: zero initial reserve imbalance" + }); + } + + function testInvalidBurnedRewardPercentage() public { + _invalidInitialization({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + burnedFeesReportingRewardPercentage: 100, + expectedErrorMessage: "NativeTokenRemote: invalid percentage" + }); + } + + function testZeroTokenHomeBlockchainID() public { + _invalidInitialization({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: bytes32(0), + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + burnedFeesReportingRewardPercentage: _DEFAULT_BURN_FEE_REWARDS_PERCENTAGE, + expectedErrorMessage: _formatErrorMessage("zero token home blockchain ID") + }); + } + + function testDeployToSameBlockchain() public { + _invalidInitialization({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + burnedFeesReportingRewardPercentage: _DEFAULT_BURN_FEE_REWARDS_PERCENTAGE, + expectedErrorMessage: _formatErrorMessage("cannot deploy to same blockchain as token home") + }); + } + + function testSendBeforeCollateralized() public { + // Need a new instance since the default set up pre-collateralizes the contract. + app = NativeTokenRemoteUpgradeable(payable(address(_createNewRemoteInstance()))); + tokenRemote = app; + nativeTokenTransferrer = app; + tokenTransferrer = app; + + vm.expectRevert("NativeTokenRemote: contract undercollateralized"); + // solhint-disable-next-line check-send-result + app.send{value: 1e17}(_createDefaultSendTokensInput()); + + // Now mark the contract as collateralized and confirm sending is enabled. + _collateralizeTokenTransferrer(); + _sendSingleHopSendSuccess(1e17, 0); + } + + function testSendAndCallBeforeCollateralized() public { + // Need a new instance since the default set up pre-collateralizes the contract. + app = NativeTokenRemoteUpgradeable(payable(address(_createNewRemoteInstance()))); + tokenRemote = app; + nativeTokenTransferrer = app; + tokenTransferrer = app; + + vm.expectRevert("NativeTokenRemote: contract undercollateralized"); + app.sendAndCall{value: 1e15}(_createDefaultSendAndCallInput()); + + // Now mark the contract as collateralized and confirm sending is enabled. + _collateralizeTokenTransferrer(); + _sendSingleHopSendSuccess(1e15, 0); + } + + function testSendWithSeparateFeeAsset() public { + uint256 amount = 2e15; + uint256 feeAmount = 100; + ExampleERC20 separateFeeAsset = new ExampleERC20(); + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.primaryFeeTokenAddress = address(separateFeeAsset); + input.primaryFee = feeAmount; + + IERC20(separateFeeAsset).safeIncreaseAllowance(address(app), feeAmount); + vm.expectCall( + address(separateFeeAsset), + abi.encodeCall(IERC20.transferFrom, (address(this), address(app), feeAmount)) + ); + + _checkExpectedTeleporterCallsForSend(_createSingleHopTeleporterMessageInput(input, amount)); + vm.expectEmit(true, true, true, true, address(app)); + emit TokensSent(_MOCK_MESSAGE_ID, address(this), input, amount); + _send(input, amount); + } + + function testTotalNativeAssetSupply() public { + uint256 initialTotalMinted = app.getTotalMinted(); + uint256 initialExpectedBalance = _DEFAULT_INITIAL_RESERVE_IMBALANCE + initialTotalMinted; + assertEq(app.totalNativeAssetSupply(), initialExpectedBalance); + + // Mock tokens being burned as tx fees. + vm.deal(app.BURNED_TX_FEES_ADDRESS(), initialExpectedBalance - 1); + assertEq(app.totalNativeAssetSupply(), 1); + + // Reset the burned tx fee amount. + vm.deal(app.BURNED_TX_FEES_ADDRESS(), 0); + assertEq(app.totalNativeAssetSupply(), initialExpectedBalance); + + // Mock tokens being transferred out by crediting them to the native token remote contract + vm.deal(app.BURNED_FOR_TRANSFER_ADDRESS(), initialExpectedBalance - 1); + assertEq(app.totalNativeAssetSupply(), 1); + + // Depositing native tokens into the contract to be wrapped native tokens shouldn't affect the supply + // of the native asset, but should be reflected in the total supply of the ERC20 representation. + app.deposit{value: 2}(); + assertEq(app.totalNativeAssetSupply(), 1); + assertEq(app.totalSupply(), 2); + } + + function testTransferToHome() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + uint256 amount = _DEFAULT_TRANSFER_AMOUNT; + vm.expectEmit(true, true, true, true, address(app)); + emit TokensSent({ + teleporterMessageID: _MOCK_MESSAGE_ID, + sender: address(this), + input: input, + amount: amount + }); + + TeleporterMessageInput memory expectedMessageInput = TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(app), amount: input.primaryFee}), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: _encodeSingleHopSendMessage(amount, input.recipient) + }); + + vm.expectCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (expectedMessageInput)) + ); + // solhint-disable-next-line check-send-result + app.send{value: amount}(input); + } + + function testReceiveSendAndCallFailureInsufficientValue() public { + uint256 amount = 200; + bytes memory payload = hex"DEADBEEF"; + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = address(app); + originInfo.senderAddress = address(this); + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + + _setUpMockMint(address(app), amount); + vm.deal(address(app), amount - 1); + vm.expectRevert("CallUtils: insufficient value"); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, DEFAULT_TOKEN_HOME_ADDRESS, message + ); + } + + function testReportBurnFeesNoNewAmount() public { + vm.expectRevert("NativeTokenRemote: burn address balance not greater than last report"); + app.reportBurnedTxFees(DEFAULT_REQUIRED_GAS_LIMIT); + } + + function testReportBurnFeesScaledToZero() public { + vm.deal(app.BURNED_TX_FEES_ADDRESS(), 1); + vm.expectRevert("NativeTokenRemote: zero scaled amount to report burn"); + app.reportBurnedTxFees(DEFAULT_REQUIRED_GAS_LIMIT); + } + + function testReportBurnFeesSuccess() public { + uint256 initialBurnedTxFeeAmount = 1e19; + uint256 expectedReward = initialBurnedTxFeeAmount / 100; // 1% of 1e17 + uint256 expectedReportedAmount = initialBurnedTxFeeAmount - expectedReward; + vm.deal(app.BURNED_TX_FEES_ADDRESS(), initialBurnedTxFeeAmount); + + _setUpMockMint(address(app), expectedReward); + TeleporterMessageInput memory expectedMessageInput = _createSingleHopTeleporterMessageInput( + SendTokensInput({ + destinationBlockchainID: app.getTokenHomeBlockchainID(), + destinationTokenTransferrerAddress: app.getTokenHomeAddress(), + recipient: app.HOME_CHAIN_BURN_ADDRESS(), + primaryFeeTokenAddress: address(app), + primaryFee: expectedReward, + secondaryFee: 0, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + multiHopFallback: address(0) + }), + expectedReportedAmount + ); + _checkExpectedTeleporterCallsForSend(expectedMessageInput); + app.reportBurnedTxFees(DEFAULT_REQUIRED_GAS_LIMIT); + + // Calling it again should revert since no additional amount as been burned. + vm.expectRevert("NativeTokenRemote: burn address balance not greater than last report"); + app.reportBurnedTxFees(DEFAULT_REQUIRED_GAS_LIMIT); + + // Mock more transaction fees being burned. + uint256 additionalBurnTxFeeAmount = 5 * 1e15 + 3; + expectedReward = additionalBurnTxFeeAmount / 100; // 1%, rounded down due to integer division. + expectedReportedAmount = additionalBurnTxFeeAmount - expectedReward; + vm.deal(app.BURNED_TX_FEES_ADDRESS(), initialBurnedTxFeeAmount + additionalBurnTxFeeAmount); + + _setUpMockMint(address(app), expectedReward); + expectedMessageInput = _createSingleHopTeleporterMessageInput( + SendTokensInput({ + destinationBlockchainID: app.getTokenHomeBlockchainID(), + destinationTokenTransferrerAddress: app.getTokenHomeAddress(), + recipient: app.HOME_CHAIN_BURN_ADDRESS(), + primaryFeeTokenAddress: address(app), + primaryFee: expectedReward, + secondaryFee: 0, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + multiHopFallback: address(0) + }), + expectedReportedAmount + ); + _checkExpectedTeleporterCallsForSend(expectedMessageInput); + app.reportBurnedTxFees(DEFAULT_REQUIRED_GAS_LIMIT); + } + + function testReportBurnFeesNoRewardSuccess() public { + // Create a new TokenRemote instance with no rewards for reporting burned fees. + app = new NativeTokenRemoteUpgradeable(ICMInitializable.Allowed); + app.initialize({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + burnedFeesReportingRewardPercentage: 0 + }); + tokenRemote = app; + nativeTokenTransferrer = app; + tokenTransferrer = app; + + uint256 burnedTxFeeAmount = 1e15; + vm.deal(app.BURNED_TX_FEES_ADDRESS(), burnedTxFeeAmount); + TeleporterMessageInput memory expectedMessageInput = _createSingleHopTeleporterMessageInput( + SendTokensInput({ + destinationBlockchainID: app.getTokenHomeBlockchainID(), + destinationTokenTransferrerAddress: app.getTokenHomeAddress(), + recipient: app.HOME_CHAIN_BURN_ADDRESS(), + primaryFeeTokenAddress: address(app), + primaryFee: 0, + secondaryFee: 0, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + multiHopFallback: address(0) + }), + burnedTxFeeAmount + ); + _checkExpectedTeleporterCallsForSend(expectedMessageInput); + app.reportBurnedTxFees(DEFAULT_REQUIRED_GAS_LIMIT); + } + + function testFallback() public { + (bool success,) = address(app).call{value: 1}("1234567812345678"); + assertTrue(success); + assertEq(app.balanceOf(address(this)), 1); + } + + function testDepositWithdrawWrappedNativeToken() public { + uint256 depositAmount = 500; + uint256 withdrawAmount = 100; + vm.deal(TEST_ACCOUNT, depositAmount); + vm.startPrank(TEST_ACCOUNT); + app.deposit{value: depositAmount}(); + assertEq(app.balanceOf(TEST_ACCOUNT), depositAmount); + app.withdraw(withdrawAmount); + assertEq(app.balanceOf(TEST_ACCOUNT), depositAmount - withdrawAmount); + assertEq(TEST_ACCOUNT.balance, withdrawAmount); + } + + function _createNewRemoteInstance() internal override returns (TokenRemote) { + NativeTokenRemoteUpgradeable instance = + new NativeTokenRemoteUpgradeable(ICMInitializable.Allowed); + instance.initialize({ + settings: TokenRemoteSettings({ + teleporterRegistryAddress: MOCK_TELEPORTER_REGISTRY_ADDRESS, + teleporterManager: address(this), + minTeleporterVersion: 1, + tokenHomeBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + tokenHomeAddress: DEFAULT_TOKEN_HOME_ADDRESS, + tokenHomeDecimals: tokenHomeDecimals + }), + nativeAssetSymbol: DEFAULT_SYMBOL, + initialReserveImbalance: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + burnedFeesReportingRewardPercentage: _DEFAULT_BURN_FEE_REWARDS_PERCENTAGE + }); + return instance; + } + + function _checkExpectedWithdrawal(address recipient, uint256 amount) internal override { + vm.expectEmit(true, true, true, true, address(tokenRemote)); + emit TokensWithdrawn(recipient, amount); + vm.mockCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeCall(INativeMinter.mintNativeCoin, (recipient, amount)), + new bytes(0) + ); + vm.expectCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeCall(INativeMinter.mintNativeCoin, (recipient, amount)) + ); + vm.deal(recipient, amount); + } + + function _setUpMockMint(address recipient, uint256 amount) internal override { + vm.mockCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeCall(INativeMinter.mintNativeCoin, (recipient, amount)), + new bytes(0) + ); + vm.expectCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeCall(INativeMinter.mintNativeCoin, (recipient, amount)) + ); + vm.deal(recipient, amount); + } + + function _setUpExpectedSendAndCall( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + address recipient, + uint256 amount, + bytes memory payload, + uint256 gasLimit, + bool targetHasCode, + bool expectSuccess + ) internal override { + vm.mockCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeCall(INativeMinter.mintNativeCoin, (address(app), amount)), + new bytes(0) + ); + vm.expectCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeCall(INativeMinter.mintNativeCoin, (address(app), amount)) + ); + + // Mock the native minter precompile crediting native balance to the contract. + vm.deal(address(app), amount); + + if (targetHasCode) { + // Non-zero code length + vm.etch(recipient, new bytes(1)); + + bytes memory expectedCalldata = abi.encodeCall( + INativeSendAndCallReceiver.receiveTokens, + ( + sourceBlockchainID, + originInfo.tokenTransferrerAddress, + originInfo.senderAddress, + payload + ) + ); + if (expectSuccess) { + vm.mockCall(recipient, amount, expectedCalldata, new bytes(0)); + } else { + vm.mockCallRevert(recipient, amount, expectedCalldata, new bytes(0)); + } + vm.expectCall(recipient, amount, uint64(gasLimit), expectedCalldata); + } else { + // No code at target + vm.etch(recipient, new bytes(0)); + } + + if (targetHasCode && expectSuccess) { + vm.expectEmit(true, true, true, true, address(app)); + emit CallSucceeded(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + } else { + vm.expectEmit(true, true, true, true, address(app)); + emit CallFailed(DEFAULT_RECIPIENT_CONTRACT_ADDRESS, amount); + } + } + + function _setUpExpectedDeposit(uint256, uint256 feeAmount) internal override { + app.deposit{value: feeAmount}(); + // Transfer the fee to the token transferrer if it is greater than 0 + if (feeAmount > 0) { + IERC20(app).safeIncreaseAllowance(address(tokenTransferrer), feeAmount); + } + + if (feeAmount > 0) { + vm.expectEmit(true, true, true, true, address(app)); + emit Transfer(address(this), address(tokenTransferrer), feeAmount); + } + } + + function _setUpExpectedZeroAmountRevert() internal override { + vm.expectRevert(_formatErrorMessage("insufficient tokens to transfer")); + } + + function _getTotalSupply() internal view override returns (uint256) { + return app.totalNativeAssetSupply(); + } + + // The native token remote contract is considered collateralized once it has received + // a message from its configured home to mint tokens. Until then, the home contract is + // still assumed to have insufficient collateral. + function _collateralizeTokenTransferrer() private { + assertFalse(app.getIsCollateralized()); + uint256 amount = 10e18; + _setUpMockMint(DEFAULT_RECIPIENT_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + app.receiveTeleporterMessage( + app.getTokenHomeBlockchainID(), + app.getTokenHomeAddress(), + _encodeSingleHopSendMessage(amount, DEFAULT_RECIPIENT_ADDRESS) + ); + assertTrue(app.getIsCollateralized()); + } + + function _invalidInitialization( + TokenRemoteSettings memory settings, + string memory nativeAssetSymbol, + uint256 initialReserveImbalance, + uint256 burnedFeesReportingRewardPercentage, + bytes memory expectedErrorMessage + ) private { + app = new NativeTokenRemoteUpgradeable(ICMInitializable.Allowed); + vm.expectRevert(expectedErrorMessage); + app.initialize( + settings, + nativeAssetSymbol, + initialReserveImbalance, + burnedFeesReportingRewardPercentage + ); + } +} diff --git a/icm-contracts/contracts/ictt/tests/NativeTokenTransferrerTests.t.sol b/icm-contracts/contracts/ictt/tests/NativeTokenTransferrerTests.t.sol new file mode 100644 index 000000000..5cfe3f37d --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/NativeTokenTransferrerTests.t.sol @@ -0,0 +1,38 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenTransferrerTest} from "./TokenTransferrerTests.t.sol"; +import {INativeTokenTransferrer} from "../interfaces/INativeTokenTransferrer.sol"; +import {SendTokensInput, SendAndCallInput} from "../interfaces/ITokenTransferrer.sol"; + +abstract contract NativeTokenTransferrerTest is TokenTransferrerTest { + INativeTokenTransferrer public nativeTokenTransferrer; + + event Deposit(address indexed sender, uint256 amount); + event Withdrawal(address indexed sender, uint256 amount); + + function testZeroSendAmount() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + _setUpExpectedZeroAmountRevert(); + _send(input, 0); + } + + function _send(SendTokensInput memory input, uint256 amount) internal virtual override { + // solhint-disable-next-line check-send-result + nativeTokenTransferrer.send{value: amount}(input); + } + + function _sendAndCall( + SendAndCallInput memory input, + uint256 amount + ) internal virtual override { + nativeTokenTransferrer.sendAndCall{value: amount}(input); + } +} diff --git a/icm-contracts/contracts/ictt/tests/StorageSlotTests.t.sol b/icm-contracts/contracts/ictt/tests/StorageSlotTests.t.sol new file mode 100644 index 000000000..278c88584 --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/StorageSlotTests.t.sol @@ -0,0 +1,79 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +// solhint-disable no-console +import {ERC20TokenHomeUpgradeable} from "../TokenHome/ERC20TokenHomeUpgradeable.sol"; +import {ERC20TokenRemoteUpgradeable} from "../TokenRemote/ERC20TokenRemoteUpgradeable.sol"; +import {NativeTokenHomeUpgradeable} from "../TokenHome/NativeTokenHomeUpgradeable.sol"; +import {NativeTokenRemoteUpgradeable} from "../TokenRemote/NativeTokenRemoteUpgradeable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +contract StorageSlotTest is Test { + function testERC20TokenHomeStorageSlot() public { + bytes32 slot = _erc7201StorageSlot("ERC20TokenHome"); + assertEq( + new ERC20TokenHomeUpgradeable(ICMInitializable.Disallowed) + .ERC20_TOKEN_HOME_STORAGE_LOCATION(), + slot + ); + } + + function testERC20TokenRemoteStorageSlot() public { + bytes32 slot = _erc7201StorageSlot("ERC20TokenRemote"); + assertEq( + new ERC20TokenRemoteUpgradeable(ICMInitializable.Disallowed) + .ERC20_TOKEN_REMOTE_STORAGE_LOCATION(), + slot + ); + } + + function testNativeTokenHomeStorageSlot() public { + bytes32 slot = _erc7201StorageSlot("NativeTokenHome"); + assertEq( + new NativeTokenHomeUpgradeable(ICMInitializable.Disallowed) + .NATIVE_TOKEN_HOME_STORAGE_LOCATION(), + slot + ); + } + + function testNativeTokenRemoteStorageSlot() public { + bytes32 slot = _erc7201StorageSlot("NativeTokenRemote"); + assertEq( + new NativeTokenRemoteUpgradeable(ICMInitializable.Disallowed) + .NATIVE_TOKEN_REMOTE_STORAGE_LOCATION(), + slot + ); + } + + function testTokenHomeStorageSlot() public { + bytes32 slot = _erc7201StorageSlot("TokenHome"); + assertEq( + new ERC20TokenHomeUpgradeable(ICMInitializable.Disallowed).TOKEN_HOME_STORAGE_LOCATION(), + slot + ); + } + + function testTokenRemoteStorageSlot() public { + bytes32 slot = _erc7201StorageSlot("TokenRemote"); + assertEq( + new NativeTokenRemoteUpgradeable(ICMInitializable.Disallowed) + .TOKEN_REMOTE_STORAGE_LOCATION(), + slot + ); + } + + function _erc7201StorageSlot( + bytes memory storageName + ) private pure returns (bytes32) { + return keccak256( + abi.encode( + uint256(keccak256(abi.encodePacked("avalanche-ictt.storage.", storageName))) - 1 + ) + ) & ~bytes32(uint256(0xff)); + } +} diff --git a/icm-contracts/contracts/ictt/tests/TokenHomeTests.t.sol b/icm-contracts/contracts/ictt/tests/TokenHomeTests.t.sol new file mode 100644 index 000000000..817e025ed --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/TokenHomeTests.t.sol @@ -0,0 +1,916 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TokenTransferrerTest} from "./TokenTransferrerTests.t.sol"; +import {TokenHome, IWarpMessenger} from "../TokenHome/TokenHome.sol"; +import {RemoteTokenTransferrerSettings} from "../TokenHome/interfaces/ITokenHome.sol"; +import {TeleporterRegistry} from "@teleporter/registry/TeleporterRegistry.sol"; +import { + SendTokensInput, + SendAndCallInput, + TransferrerMessageType, + TransferrerMessage, + MultiHopSendMessage, + RegisterRemoteMessage +} from "../interfaces/ITokenTransferrer.sol"; +import { + ITeleporterMessenger, + TeleporterMessageInput, + TeleporterFeeInfo +} from "@teleporter/ITeleporterMessenger.sol"; +import {Math} from "@openzeppelin/contracts@5.0.2/utils/math/Math.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; + +abstract contract TokenHomeTest is TokenTransferrerTest { + TokenHome public tokenHome; + + /** + * @notice The token that is transferred. + * For native assets, the wrapped token contract is used. + */ + IERC20 public transferredToken; + + event CollateralAdded( + bytes32 indexed remoteBlockchainID, + address indexed remoteTokenTransferrerAddress, + uint256 amount, + uint256 remaining + ); + + function setUp() public virtual { + vm.mockCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeWithSelector(ITeleporterMessenger.sendCrossChainMessage.selector), + abi.encode(_MOCK_MESSAGE_ID) + ); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector) + ); + + _initMockTeleporterRegistry(); + + vm.expectCall( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + abi.encodeWithSelector( + TeleporterRegistry(MOCK_TELEPORTER_REGISTRY_ADDRESS).latestVersion.selector + ) + ); + } + + function testAddCollateralRemoteNotRegistered() public { + vm.expectRevert(_formatErrorMessage("remote not registered")); + _addCollateral(DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 100); + } + + function testAddCollateralAlreadyCollateralized() public { + _setUpRegisteredRemote(DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0); + vm.expectRevert(_formatErrorMessage("zero collateral needed")); + _addCollateral(DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 100); + } + + function testAddCollateralPartialAmount() public { + uint256 initialReserveImbalance = 100; + uint256 collateralAmount = 50; + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + initialReserveImbalance + ); + _setUpExpectedDeposit(collateralAmount, 0); + vm.expectEmit(true, true, true, true, address(tokenHome)); + emit CollateralAdded( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + collateralAmount, + initialReserveImbalance - collateralAmount + ); + _addCollateral( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, collateralAmount + ); + RemoteTokenTransferrerSettings memory settings = tokenHome.getRemoteTokenTransferrerSettings( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS + ); + assertEq(settings.collateralNeeded, initialReserveImbalance - collateralAmount); + } + + function testAddCollateralMoreThanFullAmount() public { + uint256 initialReserveImbalance = 100; + uint256 collateralAmount = 150; + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + initialReserveImbalance + ); + _setUpExpectedDeposit(collateralAmount, 0); + vm.expectEmit(true, true, true, true, address(tokenHome)); + emit CollateralAdded( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + initialReserveImbalance, + 0 + ); + + uint256 excessAmount = collateralAmount - initialReserveImbalance; + _checkExpectedWithdrawal(address(this), excessAmount); + + _addCollateral( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, collateralAmount + ); + RemoteTokenTransferrerSettings memory settings = tokenHome.getRemoteTokenTransferrerSettings( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS + ); + assertEq(settings.collateralNeeded, 0); + assertTrue(address(this).balance > 0); + } + + function testSendToUnregisteredRemote() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + vm.expectRevert(_formatErrorMessage("remote not registered")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testSendDestinationNotCollateralized() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 1 + ); + vm.expectRevert(_formatErrorMessage("collateral needed for remote")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testSendZeroScaledAmount() public { + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0, 100_000, false + ); + SendTokensInput memory input = _createDefaultSendTokensInput(); + uint256 amount = 10_000; // Amount is less than the token multiplier, so will be rounded down to zero. + _setUpDeposit(amount); + vm.expectRevert(_formatErrorMessage("zero scaled amount")); + _send(input, amount); + } + + function testNonZeroFallbackRecipientForSingleHop() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + vm.expectRevert(_formatErrorMessage("non-zero multi-hop fallback")); + _send(input, 100_000); + } + + function testNonZeroFallbackRecipientForSingleHopCall() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + vm.expectRevert(_formatErrorMessage("non-zero multi-hop fallback")); + _sendAndCall(input, 100_000); + } + + function testNonZeroSecondaryFee() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.secondaryFee = 1; + vm.expectRevert(_formatErrorMessage("non-zero secondary fee")); + _send(input, 0); + } + + function testNonZeroSecondaryFeeCall() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.secondaryFee = 1; + vm.expectRevert(_formatErrorMessage("non-zero secondary fee")); + _sendAndCall(input, 0); + } + + function testReceiveInvalidMessage() public { + vm.expectRevert(); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, bytes("test") + ); + } + + function testReceiveFromNonRegisteredRemote() public { + vm.expectRevert(_formatErrorMessage("remote not registered")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeSingleHopSendMessage(1, DEFAULT_RECIPIENT_ADDRESS) + ); + } + + function testReceiveFromNonCollateralizedRemote() public { + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 100 + ); + vm.expectRevert(_formatErrorMessage("remote not collateralized")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeSingleHopSendMessage(1, DEFAULT_RECIPIENT_ADDRESS) + ); + } + + function testReceiveInsufficientTokenTransferBalance() public { + uint256 collateralAmount = 100; + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, collateralAmount + ); + _setUpExpectedDeposit(collateralAmount, 0); + _addCollateral( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, collateralAmount + ); + vm.expectRevert(_formatErrorMessage("insufficient token transfer balance")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeSingleHopSendMessage(1, DEFAULT_RECIPIENT_ADDRESS) + ); + } + + function testReceiveWithdrawSuccess() public { + uint256 amount = 200; + uint256 feeAmount = 10; + _sendSingleHopSendSuccess(amount, feeAmount); + + // Withdraw an amount less than transferred amount + uint256 withdrawAmount = amount / 2; + + _checkExpectedWithdrawal(DEFAULT_RECIPIENT_ADDRESS, withdrawAmount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeSingleHopSendMessage(withdrawAmount, DEFAULT_RECIPIENT_ADDRESS) + ); + + // Make sure the balance is correct. Only the remaining amount remains locked in the home + // contract. The rest is withdrawn. + assertEq( + tokenHome.getTransferredBalance( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS + ), + withdrawAmount + ); + } + + function testReceiveSendAndCallSuccess() public { + // First send to ç to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + bytes32 sourceBlockchainID = DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID; + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = DEFAULT_TOKEN_REMOTE_ADDRESS; + originInfo.senderAddress = address(this); + bytes memory payload = hex"DEADBEEF"; + _setUpExpectedSendAndCall({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + recipient: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + amount: amount, + payload: payload, + gasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + targetHasCode: true, + expectSuccess: true + }); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, originInfo.tokenTransferrerAddress, message + ); + } + + function testReceiveSendAndCallFailure() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 2; + _sendSingleHopSendSuccess(amount, 0); + + bytes32 sourceBlockchainID = DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID; + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = DEFAULT_TOKEN_REMOTE_ADDRESS; + originInfo.senderAddress = address(this); + bytes memory payload = hex"DEADBEEF"; + _setUpExpectedSendAndCall({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + recipient: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + amount: amount, + payload: payload, + gasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + targetHasCode: true, + expectSuccess: false + }); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, originInfo.tokenTransferrerAddress, message + ); + } + + function testReceiveMismatchedSourceBlockchainID() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + bytes memory payload = hex"DEADBEEF"; + _sendSingleHopSendSuccess(amount, 0); + + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = DEFAULT_TOKEN_REMOTE_ADDRESS; + originInfo.senderAddress = address(this); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: OTHER_BLOCKCHAIN_ID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + vm.expectRevert(_formatErrorMessage("mismatched source blockchain ID")); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, message + ); + } + + function testReceiveWrongOriginTokenTransferrerAddress() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + address originTokenTransferrerAddress = DEFAULT_TOKEN_REMOTE_ADDRESS; + bytes memory payload = hex"DEADBEEF"; + + address wrongAddress = address(0x1); + assertNotEq(originTokenTransferrerAddress, wrongAddress); + + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = wrongAddress; + originInfo.senderAddress = address(this); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + vm.expectRevert(_formatErrorMessage("mismatched origin sender address")); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, originTokenTransferrerAddress, message + ); + } + + function testMultiHopInvalidDestinationSendsToFallback() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + // The multi-hop will not be routed to the OTHER_BLOCKCHAIN_ID remote since it + // is not registered. Instead, the tokens are sent to the multi-hop fallback. + _checkExpectedWithdrawal(DEFAULT_MULTIHOP_FALLBACK_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopSendMessage({ + amount: amount, + destinationBlockchainID: OTHER_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + secondaryFee: 0, + secondaryGasLimit: 500_000, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }) + ); + } + + function testMultiHopDestinationNotCollateralized() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + _setUpRegisteredRemote(OTHER_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 100); + + // The multi-hop will not be routed to the OTHER_BLOCKCHAIN_ID remote since it is not yet + // fully collateralized. Instead, the tokens are sent to the multi-hop fallback. + _checkExpectedWithdrawal(DEFAULT_MULTIHOP_FALLBACK_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopSendMessage({ + amount: amount, + destinationBlockchainID: OTHER_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + secondaryFee: 0, + secondaryGasLimit: 500_000, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }) + ); + } + + function testMultiHopDestinationAmountScaledToZero() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 1_000; + _sendSingleHopSendSuccess(amount, 0); + + _setUpRegisteredRemote(OTHER_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0, 100_000, false); + + // The multi-hop will not be routed to the OTHER_BLOCKCHAIN_ID remote since the token + // amount would be scaled to zero. Instead, the tokens are sent to the multi-hop fallback. + _checkExpectedWithdrawal(DEFAULT_MULTIHOP_FALLBACK_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopSendMessage({ + amount: amount, + destinationBlockchainID: OTHER_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + secondaryFee: 0, + secondaryGasLimit: 500_000, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }) + ); + } + + function testMultiHopSendSuccess() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + uint256 feeAmount = 1; + uint256 transferAmount = amount - feeAmount; + SendTokensInput memory input = SendTokensInput({ + destinationBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + primaryFeeTokenAddress: address(transferredToken), + primaryFee: feeAmount, + secondaryFee: 0, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }); + _checkExpectedTeleporterCallsForSend( + _createSingleHopTeleporterMessageInput(input, transferAmount) + ); + + vm.expectEmit(true, true, true, true, address(tokenHome)); + emit TokensRouted(_MOCK_MESSAGE_ID, input, transferAmount); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopSendMessage({ + amount: amount, + destinationBlockchainID: input.destinationBlockchainID, + destinationTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + recipient: input.recipient, + secondaryFee: input.primaryFee, + secondaryGasLimit: input.requiredGasLimit, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }) + ); + } + + function testMultiHopSendInsufficientFees() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 2; + _sendSingleHopSendSuccess(amount, 0); + uint256 balanceBefore = tokenHome.getTransferredBalance( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS + ); + assertEq(balanceBefore, amount); + + // Fail due to insufficient amount to cover fees + MultiHopSendMessage memory message = MultiHopSendMessage({ + destinationBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + amount: amount, + secondaryFee: amount, + secondaryGasLimit: 50_000, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }); + + vm.expectRevert(_formatErrorMessage("insufficient amount to cover fees")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopSendMessage({ + amount: amount, + destinationBlockchainID: message.destinationBlockchainID, + destinationTokenTransferrerAddress: message.destinationTokenTransferrerAddress, + recipient: message.recipient, + secondaryFee: message.secondaryFee, + secondaryGasLimit: message.secondaryGasLimit, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }) + ); + + // Make sure the token transfer balance is still the same + assertEq( + tokenHome.getTransferredBalance( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS + ), + balanceBefore + ); + } + + function testMultiHopCallInvalidDestination() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + // The multi-hop will not be routed to the OTHER_BLOCKCHAIN_ID remote since it is not registered. + // Instead, the tokens are sent to the multi-hop fallback. + _checkExpectedWithdrawal(DEFAULT_MULTIHOP_FALLBACK_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + address originSenderAddress = address(this); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopCallMessage({ + originSenderAddress: originSenderAddress, + amount: amount, + destinationBlockchainID: OTHER_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: new bytes(16), + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS, + secondaryRequiredGasLimit: 500_000, + secondaryFee: 0 + }) + ); + } + + function testMultiHopCallDestinationNotCollateralized() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + _setUpRegisteredRemote(OTHER_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 100); + + // The multi-hop will not be routed to the OTHER_BLOCKCHAIN_ID remote since it is not yet + // fully collateralized. Instead, the tokens are sent to the multi-hop fallback. + _checkExpectedWithdrawal(DEFAULT_MULTIHOP_FALLBACK_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + address originSenderAddress = address(this); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopCallMessage({ + originSenderAddress: originSenderAddress, + amount: amount, + destinationBlockchainID: OTHER_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: new bytes(16), + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS, + secondaryRequiredGasLimit: 500_000, + secondaryFee: 0 + }) + ); + } + + function testMultiHopCallAmountScaledToZero() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 1_000; + _sendSingleHopSendSuccess(amount, 0); + + _setUpRegisteredRemote(OTHER_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0, 100_000, false); + + // The multi-hop will not be routed to the OTHER_BLOCKCHAIN_ID remote since the token + // amount would be scaled to zero. Instead, the tokens are sent to the multi-hop fallback. + _checkExpectedWithdrawal(DEFAULT_MULTIHOP_FALLBACK_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + address originSenderAddress = address(this); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopCallMessage({ + originSenderAddress: originSenderAddress, + amount: amount, + destinationBlockchainID: OTHER_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: new bytes(16), + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS, + secondaryRequiredGasLimit: 500_000, + secondaryFee: 0 + }) + ); + } + + function testMultiHopCallSuccess() public { + // First send to remote instance to increase the token transfer balance + uint256 amount = 200_000; + _sendSingleHopSendSuccess(amount, 0); + + uint256 feeAmount = 1; + uint256 transferAmount = amount - feeAmount; + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = DEFAULT_TOKEN_REMOTE_ADDRESS; + originInfo.senderAddress = address(this); + SendAndCallInput memory input = SendAndCallInput({ + destinationBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: hex"65465465", + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS, + primaryFeeTokenAddress: address(transferredToken), + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS, + primaryFee: feeAmount, + secondaryFee: 0 + }); + _checkExpectedTeleporterCallsForSend( + _createSingleHopCallTeleporterMessageInput( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, originInfo, input, transferAmount + ) + ); + + vm.expectEmit(true, true, true, true, address(tokenHome)); + emit TokensAndCallRouted(_MOCK_MESSAGE_ID, input, transferAmount); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + DEFAULT_TOKEN_REMOTE_ADDRESS, + _encodeMultiHopCallMessage({ + originSenderAddress: originInfo.senderAddress, + amount: amount, + destinationBlockchainID: input.destinationBlockchainID, + destinationTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + recipientContract: input.recipientContract, + recipientPayload: input.recipientPayload, + recipientGasLimit: input.recipientGasLimit, + fallbackRecipient: input.fallbackRecipient, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS, + secondaryRequiredGasLimit: input.requiredGasLimit, + secondaryFee: input.primaryFee + }) + ); + } + + function testRegisterRemoteZeroBlockchainID() public { + vm.expectRevert(_formatErrorMessage("zero remote blockchain ID")); + _setUpRegisteredRemote(bytes32(0), DEFAULT_TOKEN_REMOTE_ADDRESS, 0); + } + + function testRegisterRemoteSameChain() public { + bytes32 localBlockchainID = tokenHome.getBlockchainID(); + vm.expectRevert(_formatErrorMessage("cannot register remote on same chain")); + _setUpRegisteredRemote(localBlockchainID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0); + } + + function testRegisterRemoteZeroAddress() public { + vm.expectRevert(_formatErrorMessage("zero remote token transferrer address")); + _setUpRegisteredRemote(DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, address(0), 0); + } + + function testRegisterRemoteAlreadyReigstered() public { + _setUpRegisteredRemote(DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0); + vm.expectRevert(_formatErrorMessage("remote already registered")); + _setUpRegisteredRemote(DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0); + } + + function testRegisterRemoteTokenDecimalsTooHigh() public { + vm.expectRevert(_formatErrorMessage("remote token decimals too high")); + _setUpRegisteredRemote( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, 0, 1e19, true + ); + } + + function testRegisterInvalidHomeTokenDecimals() public { + vm.expectRevert(_formatErrorMessage("invalid home token decimals")); + uint8 remoteTokenDecimals = uint8(18); + RegisterRemoteMessage memory payload = RegisterRemoteMessage({ + initialReserveImbalance: 0, + homeTokenDecimals: tokenHomeDecimals + 1, + remoteTokenDecimals: uint8(remoteTokenDecimals) + }); + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.REGISTER_REMOTE, + payload: abi.encode(payload) + }); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_REMOTE_ADDRESS, abi.encode(message) + ); + } + + function testSendScaledDownAmount() public { + uint256 amount = 100; + uint256 feeAmount = 1; + + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.primaryFee = feeAmount; + + uint256 tokenMultiplier = 1e2; + + // For another destination, the raw amount sent over the wire should be divided by 1e2. + amount = 42 * tokenMultiplier; + feeAmount = 0; + input.destinationBlockchainID = OTHER_BLOCKCHAIN_ID; + input.primaryFee = feeAmount; + _setUpRegisteredRemote( + input.destinationBlockchainID, + input.destinationTokenTransferrerAddress, + 0, + tokenMultiplier, + false + ); + _setUpExpectedDeposit(amount, input.primaryFee); + TeleporterMessageInput memory expectedMessage = TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(transferredToken), + amount: input.primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: _encodeSingleHopSendMessage(amount / tokenMultiplier, DEFAULT_RECIPIENT_ADDRESS) + }); + _checkExpectedTeleporterCallsForSend(expectedMessage); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensSent(_MOCK_MESSAGE_ID, address(this), input, amount / tokenMultiplier); + _send(input, amount); + } + + function testGetTokenAddress() public view { + assertEq(address(transferredToken), address(tokenHome.getTokenAddress())); + } + + function _setUpExpectedSendAndCall( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + address recipient, + uint256 amount, + bytes memory payload, + uint256 gasLimit, + bool targetHasCode, + bool expectSuccess + ) internal virtual; + + function _addCollateral( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 amount + ) internal virtual; + + /** + * @notice Set up necessary calls to deposit funds and call `send` or `sendAndCall` + * on the token home contract. + * Different from `_setUpExpectedDeposit` since the send that follows isn't + * expected to succeed. So `setUpDeposit` does not check for expected emit events. + */ + function _setUpDeposit( + uint256 amount + ) internal virtual; + + function _setUpRegisteredRemote( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 initialReserveImbalance + ) internal virtual override { + _setUpRegisteredRemote( + remoteBlockchainID, remoteTokenTransferrerAddress, initialReserveImbalance, 1, true + ); + } + + function _setUpRegisteredRemote( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 initialReserveImbalance, + uint256 tokenMultiplier, + bool multiplyOnRemote + ) internal virtual { + uint8 remoteTokenDecimals = uint8( + multiplyOnRemote + ? tokenHomeDecimals + Math.log10(tokenMultiplier) + : tokenHomeDecimals - Math.log10(tokenMultiplier) + ); + RegisterRemoteMessage memory payload = RegisterRemoteMessage({ + initialReserveImbalance: initialReserveImbalance, + homeTokenDecimals: tokenHomeDecimals, + remoteTokenDecimals: remoteTokenDecimals + }); + TransferrerMessage memory message = TransferrerMessage({ + messageType: TransferrerMessageType.REGISTER_REMOTE, + payload: abi.encode(payload) + }); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenHome.receiveTeleporterMessage( + remoteBlockchainID, remoteTokenTransferrerAddress, abi.encode(message) + ); + } + + function _createDefaultSendTokensInput() + internal + view + override + returns (SendTokensInput memory) + { + return SendTokensInput({ + destinationBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + primaryFeeTokenAddress: address(transferredToken), + primaryFee: 0, + secondaryFee: 0, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + multiHopFallback: address(0) + }); + } + + function _createDefaultSendAndCallInput() + internal + view + override + returns (SendAndCallInput memory) + { + return SendAndCallInput({ + destinationBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: new bytes(16), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS, + multiHopFallback: address(0), + primaryFeeTokenAddress: address(transferredToken), + primaryFee: 0, + secondaryFee: 0 + }); + } + + function _createDefaultReceiveTokensInput() internal view returns (SendTokensInput memory) { + return SendTokensInput({ + destinationBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: address(tokenHome), + recipient: DEFAULT_RECIPIENT_ADDRESS, + primaryFeeTokenAddress: address(transferredToken), + primaryFee: 0, + secondaryFee: 0, + requiredGasLimit: 0, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }); + } + + function _getDefaultMessageSourceBlockchainID() internal pure override returns (bytes32) { + return DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID; + } + + function _formatErrorMessage( + string memory message + ) internal pure override returns (bytes memory) { + return bytes(string.concat("TokenHome: ", message)); + } +} diff --git a/icm-contracts/contracts/ictt/tests/TokenRemoteTests.t.sol b/icm-contracts/contracts/ictt/tests/TokenRemoteTests.t.sol new file mode 100644 index 000000000..725212f1f --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/TokenRemoteTests.t.sol @@ -0,0 +1,657 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterMessageInput, TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; +import {TokenTransferrerTest} from "./TokenTransferrerTests.t.sol"; +import {TokenRemote, IWarpMessenger} from "../TokenRemote/TokenRemote.sol"; +import {TeleporterRegistry} from "@teleporter/registry/TeleporterRegistry.sol"; +import {ITeleporterMessenger} from "@teleporter/ITeleporterMessenger.sol"; +import {TokenScalingUtils} from "@utilities/TokenScalingUtils.sol"; +import { + SendTokensInput, + SendAndCallInput, + TransferrerMessageType, + TransferrerMessage, + RegisterRemoteMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; + +abstract contract TokenRemoteTest is TokenTransferrerTest { + using SafeERC20 for IERC20; + + TokenRemote public tokenRemote; + uint8 public tokenDecimals = 18; + + function setUp() public virtual { + vm.mockCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeWithSelector(ITeleporterMessenger.sendCrossChainMessage.selector), + abi.encode(_MOCK_MESSAGE_ID) + ); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getBlockchainID, ()), + abi.encode(DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID) + ); + vm.expectCall(WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getBlockchainID, ())); + + _initMockTeleporterRegistry(); + + vm.expectCall( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + abi.encodeCall(TeleporterRegistry(MOCK_TELEPORTER_REGISTRY_ADDRESS).latestVersion, ()) + ); + } + + function testZeroDestinationBlockchain() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.destinationBlockchainID = bytes32(0); + vm.expectRevert(_formatErrorMessage("zero destination blockchain ID")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testZeroDestinationBlockchainWithSendAndCall() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.destinationBlockchainID = bytes32(0); + vm.expectRevert(_formatErrorMessage("zero destination blockchain ID")); + _sendAndCall(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testZeroDestinationTokenTransferrerAddress() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.destinationTokenTransferrerAddress = address(0); + vm.expectRevert(_formatErrorMessage("zero destination token transferrer address")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testZeroDestinationTokenTransferrerAddressWithSendAndCall() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.destinationTokenTransferrerAddress = address(0); + vm.expectRevert(_formatErrorMessage("zero destination token transferrer address")); + _sendAndCall(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testInvalidSendingBackToHomeBlockchain() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.destinationTokenTransferrerAddress = address(this); + vm.expectRevert(_formatErrorMessage("invalid destination token transferrer address")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testInvalidSendAndCallingBackToHomeBlockchain() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.destinationTokenTransferrerAddress = address(this); + vm.expectRevert(_formatErrorMessage("invalid destination token transferrer address")); + _sendAndCall(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testNonZeroSecondaryFeeToHomeBlockchain() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.secondaryFee = 1; + vm.expectRevert(_formatErrorMessage("non-zero secondary fee")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testNonZeroSecondaryFeeToHomeBlockchainCall() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.secondaryFee = 1; + vm.expectRevert(_formatErrorMessage("non-zero secondary fee")); + _sendAndCall(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testNonZeroMultiHopFallbackForSingleHop() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + vm.expectRevert(_formatErrorMessage("non-zero multi-hop fallback")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testNonZeroMultiHopFallbackForSingleHopCall() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + vm.expectRevert(_formatErrorMessage("non-zero multi-hop fallback")); + _sendAndCall(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testSendingToSameInstance() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.destinationBlockchainID = tokenRemote.getBlockchainID(); + input.destinationTokenTransferrerAddress = address(tokenRemote); + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + vm.expectRevert(_formatErrorMessage("invalid destination token transferrer address")); + _send(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testSendingToOtherInstanceOnSameChain() public { + _sendMultiHopSendSuccess(tokenRemote.getBlockchainID(), 1e18, 999, 555); + } + + function testSendAndCallingToSameInstance() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.destinationBlockchainID = tokenRemote.getBlockchainID(); + input.destinationTokenTransferrerAddress = address(tokenRemote); + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + vm.expectRevert(_formatErrorMessage("invalid destination token transferrer address")); + _sendAndCall(input, _DEFAULT_TRANSFER_AMOUNT); + } + + function testSendAndCallingToOtherInstanceOnSameChain() public { + _sendMultiHopCallSuccess(tokenRemote.getBlockchainID(), 1e18, 999, 555); + } + + function testSendZeroAmountAfterRemoveScaling() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.primaryFee = 0; + input.secondaryFee = 0; + uint256 amount = 1; + + if ( + TokenScalingUtils.removeTokenScale( + tokenRemote.getTokenMultiplier(), tokenRemote.getMultiplyOnRemote(), amount + ) != 0 + ) { + return; + } + + _setUpExpectedDeposit(amount, input.primaryFee); + vm.expectRevert(_formatErrorMessage("insufficient tokens to transfer")); + _sendAndCall(input, amount); + } + + function testSendToSameBlockchainDifferentDestination() public { + uint256 amount = 2e15; + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.destinationBlockchainID = tokenRemote.getBlockchainID(); + // Set the desintation token transferrer address to an address different than the token remote contract. + input.destinationTokenTransferrerAddress = address(0x55); + + _sendSingleHopSendSuccess(amount, input.primaryFee); + } + + function testSendMultiHopInsufficientAmountToCoverFees() public { + SendTokensInput memory input = _createDefaultSendMultiHopInput(); + uint256 amount = 1; + input.secondaryFee = 2; + _setUpExpectedDeposit(amount, input.primaryFee); + vm.expectRevert(_formatErrorMessage("insufficient tokens to transfer")); + _send(input, amount); + } + + function testSendMultiHopZeroMultiHopFallback() public { + uint256 amount = 200_000; + SendTokensInput memory input = _createDefaultSendMultiHopInput(); + input.multiHopFallback = address(0); + vm.expectRevert(_formatErrorMessage("zero multi-hop fallback")); + _send(input, amount); + } + + function testSendAndCallMultiHopZeroMultiHopFallback() public { + uint256 amount = 200_000; + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.destinationBlockchainID = OTHER_BLOCKCHAIN_ID; + input.multiHopFallback = address(0); + vm.expectRevert(_formatErrorMessage("zero multi-hop fallback")); + _sendAndCall(input, amount); + } + + function testSendMultiHopSendSuccess() public { + uint256 amount = 4e15; + uint256 primaryFee = 5; + uint256 secondaryFee = 2; + _sendMultiHopSendSuccess(OTHER_BLOCKCHAIN_ID, amount, primaryFee, secondaryFee); + } + + function testSendMultiHopCallSuccess() public { + uint256 amount = 4e18; + uint256 primaryFee = 5; + uint256 secondaryFee = 1; + _sendMultiHopCallSuccess(OTHER_BLOCKCHAIN_ID, amount, primaryFee, secondaryFee); + } + + function testReceiveInvalidSourceBlockchainID() public { + vm.expectRevert(_formatErrorMessage("invalid source blockchain ID")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, DEFAULT_TOKEN_HOME_ADDRESS, new bytes(0) + ); + } + + function testReceiveInvalidOriginSenderAddress() public { + vm.expectRevert(_formatErrorMessage("invalid origin sender address")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, address(0), new bytes(0) + ); + } + + function testReceiveInvalidMessage() public { + vm.expectRevert(); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, DEFAULT_TOKEN_HOME_ADDRESS, bytes("test") + ); + } + + function testReceiveWithdrawSuccess() public { + uint256 amount = 200; + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + _checkExpectedWithdrawal(DEFAULT_RECIPIENT_ADDRESS, amount); + uint256 initialSupply = _getTotalSupply(); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + DEFAULT_TOKEN_HOME_ADDRESS, + _encodeSingleHopSendMessage(amount, DEFAULT_RECIPIENT_ADDRESS) + ); + assertEq(_getTotalSupply(), initialSupply + amount); + } + + function testReceiveSendAndCallSuccess() public { + uint256 amount = 2; + bytes memory payload = hex"DEADBEEF"; + + bytes32 sourceBlockchainID = DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID; + OriginSenderInfo memory originInfo; + originInfo.senderAddress = address(this); + _setUpExpectedSendAndCall({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + recipient: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + amount: amount, + payload: payload, + gasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + targetHasCode: true, + expectSuccess: true + }); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + + uint256 initialSupply = _getTotalSupply(); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, DEFAULT_TOKEN_HOME_ADDRESS, message + ); + + assertEq(_getTotalSupply(), initialSupply + amount); + } + + function testReceiveSendAndCallFailure() public { + uint256 amount = 2; + bytes memory payload = hex"DEADBEEF"; + + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = address(tokenTransferrer); + originInfo.senderAddress = address(this); + _setUpExpectedSendAndCall({ + sourceBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + originInfo: originInfo, + recipient: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + amount: amount, + payload: payload, + gasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + targetHasCode: true, + expectSuccess: false + }); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, DEFAULT_TOKEN_HOME_ADDRESS, message + ); + } + + function testReceiveSendAndCallFailureNoCode() public { + uint256 amount = 2; + bytes memory payload = hex"DEADBEEF"; + + bytes32 sourceBlockchainID = DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID; + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = address(tokenTransferrer); + originInfo.senderAddress = address(this); + _setUpExpectedSendAndCall({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + recipient: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + amount: amount, + payload: payload, + gasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + targetHasCode: false, + expectSuccess: false + }); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, DEFAULT_TOKEN_HOME_ADDRESS, message + ); + } + + function testReceiveSendAndCallFailureInsufficientGas() public { + uint256 amount = 200; + bytes memory payload = hex"DEADBEEF"; + uint256 gasLimit = 5_000_000; + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = address(tokenTransferrer); + originInfo.senderAddress = address(this); + + bytes memory message = _encodeSingleHopCallMessage({ + sourceBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + originInfo: originInfo, + amount: amount, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: payload, + recipientGasLimit: gasLimit, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS + }); + + _setUpMockMint(address(tokenRemote), amount); + vm.expectRevert("CallUtils: insufficient gas"); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage{gas: gasLimit - 1}( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, DEFAULT_TOKEN_HOME_ADDRESS, message + ); + } + + function testReceiveInvalidMessageType() public { + vm.expectRevert(_formatErrorMessage("invalid message type")); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + DEFAULT_TOKEN_HOME_ADDRESS, + _encodeMultiHopSendMessage({ + amount: 1, + destinationBlockchainID: DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_REMOTE_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + secondaryFee: 0, + secondaryGasLimit: 1_000, + multiHopFallback: DEFAULT_MULTIHOP_FALLBACK_ADDRESS + }) + ); + } + + function testRegisterWithHomeSuccess() public { + // Create a new instance that has not yet received any messages. + tokenRemote = _createNewRemoteInstance(); + tokenTransferrer = tokenRemote; + + // Deploy a separate fee asset for registering with the token home. + ExampleERC20 separateFeeAsset = new ExampleERC20(); + uint256 feeAmount = 13; + TeleporterFeeInfo memory feeInfo = + TeleporterFeeInfo({feeTokenAddress: address(separateFeeAsset), amount: feeAmount}); + + IERC20(separateFeeAsset).safeIncreaseAllowance(address(tokenTransferrer), feeAmount); + vm.expectCall( + address(separateFeeAsset), + abi.encodeCall( + IERC20.transferFrom, (address(this), address(tokenTransferrer), feeAmount) + ) + ); + + TransferrerMessage memory expectedTokenTransfer = TransferrerMessage({ + messageType: TransferrerMessageType.REGISTER_REMOTE, + payload: abi.encode( + RegisterRemoteMessage({ + initialReserveImbalance: tokenRemote.getInitialReserveImbalance(), + remoteTokenDecimals: tokenDecimals, + homeTokenDecimals: tokenHomeDecimals + }) + ) + }); + TeleporterMessageInput memory expectedMessageInput = TeleporterMessageInput({ + destinationBlockchainID: tokenRemote.getTokenHomeBlockchainID(), + destinationAddress: tokenRemote.getTokenHomeAddress(), + feeInfo: feeInfo, + requiredGasLimit: tokenRemote.REGISTER_REMOTE_REQUIRED_GAS(), + allowedRelayerAddresses: new address[](0), + message: abi.encode(expectedTokenTransfer) + }); + vm.mockCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (expectedMessageInput)), + abi.encode(_MOCK_MESSAGE_ID) + ); + vm.expectCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (expectedMessageInput)) + ); + + tokenRemote.registerWithHome(feeInfo); + } + + function testRegisterWithHomeAlreadyRegistered() public { + // Mock receiving a message from the home so that the remote knows + // that it is registered already. + uint256 amount = 1; + _setUpMockMint(DEFAULT_RECIPIENT_ADDRESS, amount); + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + tokenRemote.receiveTeleporterMessage( + tokenRemote.getTokenHomeBlockchainID(), + tokenRemote.getTokenHomeAddress(), + _encodeSingleHopSendMessage(amount, DEFAULT_RECIPIENT_ADDRESS) + ); + + vm.expectRevert(_formatErrorMessage("already registered")); + tokenRemote.registerWithHome(TeleporterFeeInfo({feeTokenAddress: address(0), amount: 0})); + } + + function testCalculateNumWords() public view { + assertEq(tokenRemote.calculateNumWords(0), 0); + assertEq(tokenRemote.calculateNumWords(1), 1); + assertEq(tokenRemote.calculateNumWords(32), 1); + assertEq(tokenRemote.calculateNumWords(33), 2); + assertEq(tokenRemote.calculateNumWords(64), 2); + assertEq(tokenRemote.calculateNumWords(65), 3); + } + + function _sendMultiHopSendSuccess( + bytes32 destinationBlockchainID, + uint256 amount, + uint256 primaryFee, + uint256 secondaryFee + ) internal { + uint256 transferAmount = amount; + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.destinationBlockchainID = destinationBlockchainID; + input.primaryFee = primaryFee; + input.secondaryFee = secondaryFee; + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + + _setUpExpectedDeposit(amount, input.primaryFee); + _checkExpectedTeleporterCallsForSend( + _createMultiHopSendTeleporterMessageInput(input, transferAmount) + ); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensSent(_MOCK_MESSAGE_ID, address(this), input, transferAmount); + _send(input, amount); + } + + function _sendMultiHopCallSuccess( + bytes32 destinationBlockchainID, + uint256 amount, + uint256 primaryFee, + uint256 secondaryFee + ) internal { + uint256 transferAmount = amount; + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.destinationBlockchainID = destinationBlockchainID; + input.primaryFee = primaryFee; + input.secondaryFee = secondaryFee; + input.multiHopFallback = DEFAULT_MULTIHOP_FALLBACK_ADDRESS; + + _setUpExpectedDeposit(amount, input.primaryFee); + + // Only tokens destinations scale tokens, so isReceive is always false here. + address originSenderAddress = address(this); + + _checkExpectedTeleporterCallsForSend( + _createMultiHopCallTeleporterMessageInput(originSenderAddress, input, transferAmount) + ); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensAndCallSent(_MOCK_MESSAGE_ID, originSenderAddress, input, transferAmount); + _sendAndCall(input, amount); + } + + function _setUpMockMint(address recipient, uint256 amount) internal virtual; + + function _setUpExpectedSendAndCall( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + address recipient, + uint256 amount, + bytes memory payload, + uint256 gasLimit, + bool targetHasCode, + bool expectSuccess + ) internal virtual; + + // Remotes don't need to register supported remotes because they + // only send messages to their configured token home. + function _setUpRegisteredRemote(bytes32, address, uint256) internal virtual override { + return; + } + + function _createNewRemoteInstance() internal virtual returns (TokenRemote); + + function _getTotalSupply() internal view virtual returns (uint256); + + function _createMultiHopSendTeleporterMessageInput( + SendTokensInput memory input, + uint256 transferAmount + ) internal view returns (TeleporterMessageInput memory) { + return TeleporterMessageInput({ + destinationBlockchainID: tokenRemote.getTokenHomeBlockchainID(), + destinationAddress: tokenRemote.getTokenHomeAddress(), + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(tokenRemote), amount: input.primaryFee}), + requiredGasLimit: tokenRemote.MULTI_HOP_SEND_REQUIRED_GAS(), + allowedRelayerAddresses: new address[](0), + message: _encodeMultiHopSendMessage({ + amount: transferAmount, + destinationBlockchainID: input.destinationBlockchainID, + destinationTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + recipient: input.recipient, + secondaryFee: input.secondaryFee, + secondaryGasLimit: input.requiredGasLimit, + multiHopFallback: input.multiHopFallback + }) + }); + } + + function _createMultiHopCallTeleporterMessageInput( + address originSenderAddress, + SendAndCallInput memory input, + uint256 transferAmount + ) internal view returns (TeleporterMessageInput memory) { + return TeleporterMessageInput({ + destinationBlockchainID: tokenRemote.getTokenHomeBlockchainID(), + destinationAddress: tokenRemote.getTokenHomeAddress(), + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(tokenRemote), amount: input.primaryFee}), + requiredGasLimit: tokenRemote.MULTI_HOP_CALL_REQUIRED_GAS() + + ( + tokenRemote.calculateNumWords(input.recipientPayload.length) + * tokenRemote.MULTI_HOP_CALL_GAS_PER_WORD() + ), + allowedRelayerAddresses: new address[](0), + message: _encodeMultiHopCallMessage({ + originSenderAddress: originSenderAddress, + amount: transferAmount, + destinationBlockchainID: input.destinationBlockchainID, + destinationTokenTransferrerAddress: input.destinationTokenTransferrerAddress, + recipientContract: input.recipientContract, + recipientPayload: input.recipientPayload, + recipientGasLimit: input.recipientGasLimit, + fallbackRecipient: input.fallbackRecipient, + multiHopFallback: input.multiHopFallback, + secondaryRequiredGasLimit: input.requiredGasLimit, + secondaryFee: input.secondaryFee + }) + }); + } + + function _createDefaultSendTokensInput() + internal + view + override + returns (SendTokensInput memory) + { + return SendTokensInput({ + destinationBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_HOME_ADDRESS, + recipient: DEFAULT_RECIPIENT_ADDRESS, + primaryFeeTokenAddress: address(tokenRemote), + primaryFee: 0, + secondaryFee: 0, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + multiHopFallback: address(0) + }); + } + + function _createDefaultSendMultiHopInput() internal view returns (SendTokensInput memory) { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.destinationBlockchainID = OTHER_BLOCKCHAIN_ID; + input.multiHopFallback = DEFAULT_FALLBACK_RECIPIENT_ADDRESS; + return input; + } + + function _createDefaultSendAndCallInput() + internal + view + override + returns (SendAndCallInput memory) + { + return SendAndCallInput({ + destinationBlockchainID: DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID, + destinationTokenTransferrerAddress: DEFAULT_TOKEN_HOME_ADDRESS, + recipientContract: DEFAULT_RECIPIENT_CONTRACT_ADDRESS, + recipientPayload: new bytes(16), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + recipientGasLimit: DEFAULT_RECIPIENT_GAS_LIMIT, + fallbackRecipient: DEFAULT_FALLBACK_RECIPIENT_ADDRESS, + multiHopFallback: address(0), + primaryFeeTokenAddress: address(tokenRemote), + primaryFee: 0, + secondaryFee: 0 + }); + } + + function _getDefaultMessageSourceBlockchainID() internal pure override returns (bytes32) { + return DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID; + } + + function _formatErrorMessage( + string memory message + ) internal pure override returns (bytes memory) { + return bytes(string.concat("TokenRemote: ", message)); + } +} diff --git a/icm-contracts/contracts/ictt/tests/TokenTransferrerTests.t.sol b/icm-contracts/contracts/ictt/tests/TokenTransferrerTests.t.sol new file mode 100644 index 000000000..627df6981 --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/TokenTransferrerTests.t.sol @@ -0,0 +1,478 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {TeleporterRegistry} from "@teleporter/registry/TeleporterRegistry.sol"; +import { + ITeleporterMessenger, + TeleporterMessageInput, + TeleporterFeeInfo +} from "@teleporter/ITeleporterMessenger.sol"; +import { + ITokenTransferrer, + SendTokensInput, + SendAndCallInput, + TransferrerMessageType, + TransferrerMessage, + SingleHopSendMessage, + SingleHopCallMessage, + MultiHopSendMessage, + MultiHopCallMessage +} from "../interfaces/ITokenTransferrer.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {IERC20Errors} from "@openzeppelin/contracts@5.0.2/interfaces/draft-IERC6093.sol"; + +abstract contract TokenTransferrerTest is Test { + // convenience struct to reduce stack usage + struct OriginSenderInfo { + address tokenTransferrerAddress; + address senderAddress; + } + + bytes32 public constant DEFAULT_TOKEN_HOME_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + bytes32 public constant DEFAULT_TOKEN_REMOTE_BLOCKCHAIN_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes32 public constant OTHER_BLOCKCHAIN_ID = + bytes32(hex"9876987698769876987698769876987698769876987698769876987698769876"); + address public constant DEFAULT_TOKEN_REMOTE_ADDRESS = + 0xd878229c9c3575F224784DE610911B5607a3ad15; + address public constant DEFAULT_TOKEN_HOME_ADDRESS = 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + address public constant DEFAULT_SENDER_ADDRESS = 0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5; + address public constant DEFAULT_RECIPIENT_ADDRESS = 0xABCDabcdABcDabcDaBCDAbcdABcdAbCdABcDABCd; + address public constant DEFAULT_RECIPIENT_CONTRACT_ADDRESS = + 0xa83114A443dA1CecEFC50368531cACE9F37fCCcb; + uint256 public constant DEFAULT_REQUIRED_GAS_LIMIT = 200_000; + uint256 public constant DEFAULT_RECIPIENT_GAS_LIMIT = 100_000; + address public constant DEFAULT_MULTIHOP_FALLBACK_ADDRESS = + 0x043448b3FE2F24522D9CeB32AD8623c0b6b53E26; + address public constant DEFAULT_FALLBACK_RECIPIENT_ADDRESS = + 0xe69Ea1BAF997002602c0A3D451b2b5c9B7F8E6A1; + address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; + address public constant NATIVE_MINTER_PRECOMPILE_ADDRESS = + address(0x0200000000000000000000000000000000000001); + address public constant MOCK_TELEPORTER_MESSENGER_ADDRESS = + 0x644E5b7c5D4Bc8073732CEa72c66e0BB90dFC00f; + address public constant MOCK_TELEPORTER_REGISTRY_ADDRESS = + 0xf9FA4a0c696b659328DDaaBCB46Ae4eBFC9e68e4; + bytes32 internal constant _MOCK_MESSAGE_ID = + bytes32(hex"1111111111111111111111111111111111111111111111111111111111111111"); + + uint256 internal constant _DEFAULT_FEE_AMOUNT = 123456; + uint256 internal constant _DEFAULT_TRANSFER_AMOUNT = 1e18; + uint256 internal constant _DEFAULT_INITIAL_RESERVE_IMBALANCE = 1e18; + uint256 internal constant _DEFAULT_BURN_FEE_REWARDS_PERCENTAGE = 1; + + uint8 public tokenHomeDecimals; + + ITokenTransferrer public tokenTransferrer; + + event TokensSent( + bytes32 indexed teleporterMessageID, + address indexed sender, + SendTokensInput input, + uint256 amount + ); + event TokensRouted(bytes32 indexed teleporterMessageID, SendTokensInput input, uint256 amount); + event TokensAndCallSent( + bytes32 indexed teleporterMessageID, + address indexed sender, + SendAndCallInput input, + uint256 amount + ); + event TokensAndCallRouted( + bytes32 indexed teleporterMessageID, SendAndCallInput input, uint256 amount + ); + + event TokensWithdrawn(address indexed recipient, uint256 amount); + event CallSucceeded(address indexed recipientContract, uint256 amount); + event CallFailed(address indexed recipientContract, uint256 amount); + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + + function testSendZeroRecipient() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.recipient = address(0); + vm.expectRevert(_formatErrorMessage("zero recipient address")); + _send(input, 0); + } + + function testSendAndCallZeroRecipientContract() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.recipientContract = address(0); + vm.expectRevert(_formatErrorMessage("zero recipient contract address")); + _sendAndCall(input, 0); + } + + function testSendZeroRequiredGasLimit() public { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.requiredGasLimit = 0; + vm.expectRevert(_formatErrorMessage("zero required gas limit")); + _send(input, 0); + } + + function testSendAndCallZeroRequiredGasLimit() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.requiredGasLimit = 0; + vm.expectRevert(_formatErrorMessage("zero required gas limit")); + _sendAndCall(input, 0); + } + + function testSendAndCallZeroRecipientGasLimit() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.recipientGasLimit = 0; + vm.expectRevert(_formatErrorMessage("zero recipient gas limit")); + _sendAndCall(input, 0); + } + + function testSendAndCallInvalidRecipientGasLimit() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.recipientGasLimit = input.requiredGasLimit + 1; + vm.expectRevert(_formatErrorMessage("invalid recipient gas limit")); + _sendAndCall(input, 0); + } + + function testSendAndCallZeroFallbackRecipient() public { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.fallbackRecipient = address(0); + vm.expectRevert(_formatErrorMessage("zero fallback recipient address")); + _sendAndCall(input, 0); + } + + function testSendWithNoFeeAllowance() public { + uint256 amount = 2e15; + uint256 primaryFee = 100; + + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.primaryFee = primaryFee; + + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + _setUpExpectedDeposit(amount, 0); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, tokenTransferrer, 0, primaryFee + ) + ); + _send(input, amount); + } + + function testSendAndCallWithNoFeeAllowance() public { + uint256 amount = 2e15; + uint256 primaryFee = 100; + + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.primaryFee = primaryFee; + + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + _setUpExpectedDeposit(amount, 0); + vm.expectRevert( + abi.encodeWithSelector( + IERC20Errors.ERC20InsufficientAllowance.selector, tokenTransferrer, 0, primaryFee + ) + ); + _sendAndCall(input, amount); + } + + function testSendWithFees() public { + uint256 amount = 2e15; + uint256 primaryFee = 100; + _sendSingleHopSendSuccess(amount, primaryFee); + } + + function testSendNoFees() public { + uint256 amount = 2e15; + uint256 primaryFee = 0; + _sendSingleHopSendSuccess(amount, primaryFee); + } + + function testSendAndCallWithFees() public { + uint256 amount = 1e17; + uint256 primaryFee = 10; + _sendSingleHopCallSuccess(amount, primaryFee); + } + + function _initMockTeleporterRegistry() internal { + vm.mockCall( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + abi.encodeWithSelector( + TeleporterRegistry(MOCK_TELEPORTER_REGISTRY_ADDRESS).latestVersion.selector + ), + abi.encode(1) + ); + + vm.mockCall( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + abi.encodeWithSelector(TeleporterRegistry.getVersionFromAddress.selector), + abi.encode(1) + ); + + vm.mockCall( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + abi.encodeWithSelector(TeleporterRegistry.getAddressFromVersion.selector, (1)), + abi.encode(MOCK_TELEPORTER_MESSENGER_ADDRESS) + ); + + vm.mockCall( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + abi.encodeWithSelector(TeleporterRegistry.getLatestTeleporter.selector), + abi.encode(ITeleporterMessenger(MOCK_TELEPORTER_MESSENGER_ADDRESS)) + ); + + vm.mockCall( + MOCK_TELEPORTER_REGISTRY_ADDRESS, + abi.encodeWithSelector(TeleporterRegistry.getVersionFromAddress.selector), + abi.encode(1) + ); + } + + function _send(SendTokensInput memory input, uint256 amount) internal virtual; + + function _sendAndCall(SendAndCallInput memory input, uint256 amount) internal virtual; + + function _sendSingleHopSendSuccess(uint256 amount, uint256 feeAmount) internal { + SendTokensInput memory input = _createDefaultSendTokensInput(); + input.primaryFee = feeAmount; + + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + _setUpExpectedDeposit(amount, input.primaryFee); + _checkExpectedTeleporterCallsForSend(_createSingleHopTeleporterMessageInput(input, amount)); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensSent(_MOCK_MESSAGE_ID, address(this), input, amount); + _send(input, amount); + } + + function _sendSingleHopCallSuccess(uint256 amount, uint256 feeAmount) internal { + SendAndCallInput memory input = _createDefaultSendAndCallInput(); + input.primaryFee = feeAmount; + + _setUpRegisteredRemote( + input.destinationBlockchainID, input.destinationTokenTransferrerAddress, 0 + ); + _setUpExpectedDeposit(amount, input.primaryFee); + OriginSenderInfo memory originInfo; + originInfo.tokenTransferrerAddress = address(tokenTransferrer); + originInfo.senderAddress = address(this); + _checkExpectedTeleporterCallsForSend( + _createSingleHopCallTeleporterMessageInput( + _getDefaultMessageSourceBlockchainID(), originInfo, input, amount + ) + ); + vm.expectEmit(true, true, true, true, address(tokenTransferrer)); + emit TokensAndCallSent(_MOCK_MESSAGE_ID, address(this), input, amount); + _sendAndCall(input, amount); + } + + function _setUpRegisteredRemote( + bytes32 remoteBlockchainID, + address remoteTokenTransferrerAddress, + uint256 initialReserveImbalance + ) internal virtual; + + function _setUpExpectedDeposit(uint256 amount, uint256 feeAmount) internal virtual; + + function _setUpExpectedZeroAmountRevert() internal virtual; + + function _checkExpectedWithdrawal(address recipient, uint256 amount) internal virtual; + + function _checkExpectedTeleporterCallsForSend( + TeleporterMessageInput memory expectedMessageInput + ) internal { + if (expectedMessageInput.feeInfo.amount > 0) { + vm.expectCall( + expectedMessageInput.feeInfo.feeTokenAddress, + abi.encodeCall( + IERC20.allowance, + (address(tokenTransferrer), address(MOCK_TELEPORTER_MESSENGER_ADDRESS)) + ) + ); + } + vm.mockCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (expectedMessageInput)), + abi.encode(_MOCK_MESSAGE_ID) + ); + vm.expectCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (expectedMessageInput)) + ); + } + + // This function is overridden by TeleporterTokenDestinationTests + function _scaleTokens(uint256 amount, bool) internal virtual returns (uint256) { + return amount; + } + + function _createDefaultSendTokensInput() + internal + view + virtual + returns (SendTokensInput memory); + + function _createDefaultSendAndCallInput() + internal + view + virtual + returns (SendAndCallInput memory); + + function _createSingleHopTeleporterMessageInput( + SendTokensInput memory input, + uint256 transferAmount + ) internal pure returns (TeleporterMessageInput memory) { + return TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(input.primaryFeeTokenAddress), + amount: input.primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: _encodeSingleHopSendMessage(transferAmount, input.recipient) + }); + } + + function _createSingleHopCallTeleporterMessageInput( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + SendAndCallInput memory input, + uint256 transferAmount + ) internal pure returns (TeleporterMessageInput memory) { + return TeleporterMessageInput({ + destinationBlockchainID: input.destinationBlockchainID, + destinationAddress: input.destinationTokenTransferrerAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(input.primaryFeeTokenAddress), + amount: input.primaryFee + }), + requiredGasLimit: input.requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: _encodeSingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originInfo: originInfo, + amount: transferAmount, + recipientContract: input.recipientContract, + recipientPayload: input.recipientPayload, + recipientGasLimit: input.recipientGasLimit, + fallbackRecipient: input.fallbackRecipient + }) + }); + } + + function _getDefaultMessageSourceBlockchainID() internal pure virtual returns (bytes32); + + function _formatErrorMessage( + string memory message + ) internal pure virtual returns (bytes memory); + + function _encodeSingleHopSendMessage( + uint256 amount, + address recipient + ) internal pure returns (bytes memory) { + return abi.encode( + TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_SEND, + payload: abi.encode(SingleHopSendMessage({recipient: recipient, amount: amount})) + }) + ); + } + + function _encodeSingleHopCallMessage( + bytes32 sourceBlockchainID, + OriginSenderInfo memory originInfo, + uint256 amount, + address recipientContract, + bytes memory recipientPayload, + uint256 recipientGasLimit, + address fallbackRecipient + ) internal pure returns (bytes memory) { + return abi.encode( + TransferrerMessage({ + messageType: TransferrerMessageType.SINGLE_HOP_CALL, + payload: abi.encode( + SingleHopCallMessage({ + sourceBlockchainID: sourceBlockchainID, + originTokenTransferrerAddress: originInfo.tokenTransferrerAddress, + originSenderAddress: originInfo.senderAddress, + recipientContract: recipientContract, + amount: amount, + recipientPayload: recipientPayload, + recipientGasLimit: recipientGasLimit, + fallbackRecipient: fallbackRecipient + }) + ) + }) + ); + } + + function _encodeMultiHopSendMessage( + uint256 amount, + bytes32 destinationBlockchainID, + address destinationTokenTransferrerAddress, + address recipient, + uint256 secondaryFee, + uint256 secondaryGasLimit, + address multiHopFallback + ) internal pure returns (bytes memory) { + return abi.encode( + TransferrerMessage({ + messageType: TransferrerMessageType.MULTI_HOP_SEND, + payload: abi.encode( + MultiHopSendMessage({ + destinationBlockchainID: destinationBlockchainID, + destinationTokenTransferrerAddress: destinationTokenTransferrerAddress, + recipient: recipient, + amount: amount, + secondaryFee: secondaryFee, + secondaryGasLimit: secondaryGasLimit, + multiHopFallback: multiHopFallback + }) + ) + }) + ); + } + + function _encodeMultiHopCallMessage( + address originSenderAddress, + uint256 amount, + bytes32 destinationBlockchainID, + address destinationTokenTransferrerAddress, + address recipientContract, + bytes memory recipientPayload, + uint256 recipientGasLimit, + address fallbackRecipient, + address multiHopFallback, + uint256 secondaryRequiredGasLimit, + uint256 secondaryFee + ) internal pure returns (bytes memory) { + return abi.encode( + TransferrerMessage({ + messageType: TransferrerMessageType.MULTI_HOP_CALL, + payload: abi.encode( + MultiHopCallMessage({ + originSenderAddress: originSenderAddress, + destinationBlockchainID: destinationBlockchainID, + destinationTokenTransferrerAddress: destinationTokenTransferrerAddress, + recipientContract: recipientContract, + amount: amount, + recipientPayload: recipientPayload, + recipientGasLimit: recipientGasLimit, + fallbackRecipient: fallbackRecipient, + multiHopFallback: multiHopFallback, + secondaryRequiredGasLimit: secondaryRequiredGasLimit, + secondaryFee: secondaryFee + }) + ) + }) + ); + } +} diff --git a/icm-contracts/contracts/ictt/tests/WrappedNativeTokenTests.t.sol b/icm-contracts/contracts/ictt/tests/WrappedNativeTokenTests.t.sol new file mode 100644 index 000000000..4bb551f2d --- /dev/null +++ b/icm-contracts/contracts/ictt/tests/WrappedNativeTokenTests.t.sol @@ -0,0 +1,36 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {WrappedNativeToken} from "../WrappedNativeToken.sol"; + +contract WrappedNativeTokenTest is Test { + address public constant TEST_ACCOUNT = 0xd4E96eF8eee8678dBFf4d535E033Ed1a4F7605b7; + WrappedNativeToken public wavax; + + function setUp() public virtual { + wavax = new WrappedNativeToken("AVAX"); + } + + function testFallback() public { + (bool success,) = address(wavax).call{value: 1}("1234567812345678"); + assertTrue(success); + assertEq(wavax.balanceOf(address(this)), 1); + } + + function testDepositWithdraw() public { + uint256 depositAmount = 500; + uint256 withdrawAmount = 100; + vm.deal(TEST_ACCOUNT, depositAmount); + vm.startPrank(TEST_ACCOUNT); + wavax.deposit{value: depositAmount}(); + assertEq(wavax.balanceOf(TEST_ACCOUNT), depositAmount); + wavax.withdraw(withdrawAmount); + assertEq(wavax.balanceOf(TEST_ACCOUNT), depositAmount - withdrawAmount); + assertEq(TEST_ACCOUNT.balance, withdrawAmount); + } +} diff --git a/icm-contracts/contracts/mocks/ExampleERC20.sol b/icm-contracts/contracts/mocks/ExampleERC20.sol new file mode 100644 index 000000000..bda9fbb7a --- /dev/null +++ b/icm-contracts/contracts/mocks/ExampleERC20.sol @@ -0,0 +1,43 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + * DO NOT USE THIS CODE IN PRODUCTION. + */ +import { + ERC20Burnable, + ERC20 +} from "@openzeppelin/contracts@5.0.2/token/ERC20/extensions/ERC20Burnable.sol"; +import {IERC20Mintable} from "../validator-manager/interfaces/IERC20Mintable.sol"; + +contract ExampleERC20 is ERC20Burnable, IERC20Mintable { + string private constant _TOKEN_NAME = "Mock Token"; + string private constant _TOKEN_SYMBOL = "EXMP"; + + uint256 private constant _MAX_MINT = 1e19; + + constructor() ERC20(_TOKEN_NAME, _TOKEN_SYMBOL) { + _mint(msg.sender, 1e28); + } + + function mint( + uint256 amount + ) external { + // Can only mint 10 at a time. + require(amount <= _MAX_MINT, "ExampleERC20: max mint exceeded"); + + _mint(msg.sender, amount); + } + + function mint(address account, uint256 amount) external { + // Can only mint 10 at a time. + require(amount <= _MAX_MINT, "ExampleERC20: max mint exceeded"); + + _mint(account, amount); + } +} diff --git a/icm-contracts/contracts/mocks/UnitTestMockERC20.sol b/icm-contracts/contracts/mocks/UnitTestMockERC20.sol new file mode 100644 index 000000000..aeffe234b --- /dev/null +++ b/icm-contracts/contracts/mocks/UnitTestMockERC20.sol @@ -0,0 +1,58 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + * DO NOT USE THIS CODE IN PRODUCTION. + */ + +// A mock contract for use in unit tests. +contract UnitTestMockERC20 { + mapping(address account => uint256 balance) public mockBalances; + mapping(address sender => uint256 feeAmount) public feeOnTransferSenders; + mapping(address owner => mapping(address spender => uint256)) public mockAllowances; + + // If an address on feeOnTransferSenders is the sender address in a transferFrom call, + // the amount credited to the receiving account is reduced by the feeAmount set for the + // sender. This is to mock "fee on token transfer" functionality of select ERC20 contracts. + function setFeeOnTransferSender(address sender, uint256 feeAmount) public { + feeOnTransferSenders[sender] = feeAmount; + } + + // The mock allows anyone to call transferFrom to increment the balance of the + // receipt address. Neither the call or sender need to have sufficient balances to send, + // we just increment the balance the of the recipient. + function transferFrom(address from, address to, uint256 amount) public returns (bool) { + uint256 feeAmount = feeOnTransferSenders[from]; + mockBalances[to] += (amount - feeAmount); + return true; + } + + // The mock allows anyone to call transferFrom to increment the balance of the + // receipt address. Neither the caller or sender need to have sufficient balances to send, + // we just increment the balance the of the recipient. + function transfer(address to, uint256 amount) public returns (bool) { + uint256 feeAmount = feeOnTransferSenders[msg.sender]; + mockBalances[to] += (amount - feeAmount); + return true; + } + + function approve(address spender, uint256 amount) public returns (bool) { + mockAllowances[msg.sender][spender] = amount; + return true; + } + + function balanceOf( + address account + ) public view returns (uint256) { + return mockBalances[account]; + } + + function allowance(address owner, address spender) public view returns (uint256) { + return mockAllowances[owner][spender]; + } +} diff --git a/icm-contracts/contracts/subnet-evm/IAllowList.sol b/icm-contracts/contracts/subnet-evm/IAllowList.sol new file mode 100644 index 000000000..7fd4c5d2d --- /dev/null +++ b/icm-contracts/contracts/subnet-evm/IAllowList.sol @@ -0,0 +1,33 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +interface IAllowList { + event RoleSet( + uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole + ); + + // Set [addr] to have the admin role over the precompile contract. + function setAdmin( + address addr + ) external; + + // Set [addr] to be enabled on the precompile contract. + function setEnabled( + address addr + ) external; + + // Set [addr] to have the manager role over the precompile contract. + function setManager( + address addr + ) external; + + // Set [addr] to have no role for the precompile contract. + function setNone( + address addr + ) external; + + // Read the status of [addr]. + function readAllowList( + address addr + ) external view returns (uint256 role); +} diff --git a/icm-contracts/contracts/subnet-evm/INativeMinter.sol b/icm-contracts/contracts/subnet-evm/INativeMinter.sol new file mode 100644 index 000000000..fcf047e39 --- /dev/null +++ b/icm-contracts/contracts/subnet-evm/INativeMinter.sol @@ -0,0 +1,11 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {IAllowList} from "@subnet-evm/IAllowList.sol"; + +interface INativeMinter is IAllowList { + event NativeCoinMinted(address indexed sender, address indexed recipient, uint256 amount); + // Mint [amount] number of native coins and send to [addr] + + function mintNativeCoin(address addr, uint256 amount) external; +} diff --git a/icm-contracts/contracts/subnet-evm/IWarpMessenger.sol b/icm-contracts/contracts/subnet-evm/IWarpMessenger.sol new file mode 100644 index 000000000..97798024f --- /dev/null +++ b/icm-contracts/contracts/subnet-evm/IWarpMessenger.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.25; + +struct WarpMessage { + bytes32 sourceChainID; + address originSenderAddress; + bytes payload; +} + +struct WarpBlockHash { + bytes32 sourceChainID; + bytes32 blockHash; +} + +interface IWarpMessenger { + event SendWarpMessage(address indexed sender, bytes32 indexed messageID, bytes message); + + // sendWarpMessage emits a request for the subnet to send a warp message from [msg.sender] + // with the specified parameters. + // This emits a SendWarpMessage log from the precompile. When the corresponding block is accepted + // the Accept hook of the Warp precompile is invoked with all accepted logs emitted by the Warp + // precompile. + // Each validator then adds the UnsignedWarpMessage encoded in the log to the set of messages + // it is willing to sign for an off-chain relayer to aggregate Warp signatures. + function sendWarpMessage( + bytes calldata payload + ) external returns (bytes32 messageID); + + // getVerifiedWarpMessage parses the pre-verified warp message in the + // predicate storage slots as a WarpMessage and returns it to the caller. + // If the message exists and passes verification, returns the verified message + // and true. + // Otherwise, returns false and the empty value for the message. + function getVerifiedWarpMessage( + uint32 index + ) external view returns (WarpMessage calldata message, bool valid); + + // getVerifiedWarpBlockHash parses the pre-verified WarpBlockHash message in the + // predicate storage slots as a WarpBlockHash message and returns it to the caller. + // If the message exists and passes verification, returns the verified message + // and true. + // Otherwise, returns false and the empty value for the message. + function getVerifiedWarpBlockHash( + uint32 index + ) external view returns (WarpBlockHash calldata warpBlockHash, bool valid); + + // getBlockchainID returns the snow.Context BlockchainID of this chain. + // This blockchainID is the hash of the transaction that created this blockchain on the P-Chain + // and is not related to the Ethereum ChainID. + function getBlockchainID() external view returns (bytes32 blockchainID); +} diff --git a/icm-contracts/contracts/teleporter/ITeleporterMessenger.sol b/icm-contracts/contracts/teleporter/ITeleporterMessenger.sol new file mode 100644 index 000000000..5a062718d --- /dev/null +++ b/icm-contracts/contracts/teleporter/ITeleporterMessenger.sol @@ -0,0 +1,271 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +// A message receipt identifies the message that was delivered by its nonce, +// and the address that can redeem the reward for that message. +struct TeleporterMessageReceipt { + uint256 receivedMessageNonce; + address relayerRewardAddress; +} + +// Represents all of the information required for submitting a Teleporter message +// to be sent to the given destination chain ID and address. Includes the fee +// information for the message, the amount of gas the relayer must provide to execute +// the message on the destination chain, the relayer accounts allowed to deliver the +// message, and the message data itself. +struct TeleporterMessageInput { + bytes32 destinationBlockchainID; + address destinationAddress; + TeleporterFeeInfo feeInfo; + uint256 requiredGasLimit; + address[] allowedRelayerAddresses; + bytes message; +} + +// Represents a message sent or received by an implementation of {ITeleporterMessenger}. +struct TeleporterMessage { + uint256 messageNonce; + address originSenderAddress; + bytes32 destinationBlockchainID; + address destinationAddress; + uint256 requiredGasLimit; + address[] allowedRelayerAddresses; + TeleporterMessageReceipt[] receipts; + bytes message; +} + +// Represents the fee information associated to a given Teleporter message. +// The contract address is the asset contract the fee will be paid in, and +// the amount is the amount of that specified asset. +struct TeleporterFeeInfo { + address feeTokenAddress; + uint256 amount; +} + +/** + * @dev Interface that describes functionalities for a cross-chain messenger implementing the Teleporter protcol. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface ITeleporterMessenger { + /** + * @notice Emitted when the blockchain ID of the contract instance is initialized using the Warp precompile. + */ + event BlockchainIDInitialized(bytes32 indexed blockchainID); + + /** + * @notice Emitted when sending a Teleporter message cross-chain. + */ + event SendCrossChainMessage( + bytes32 indexed messageID, + bytes32 indexed destinationBlockchainID, + TeleporterMessage message, + TeleporterFeeInfo feeInfo + ); + + /** + * @notice Emitted when an additional fee amount is added to a Teleporter message that had previously + * been sent, but not yet delivered to the destination chain. + */ + event AddFeeAmount(bytes32 indexed messageID, TeleporterFeeInfo updatedFeeInfo); + + /** + * @notice Emitted when a Teleporter message is being delivered on the destination chain to an address, + * but message execution fails. Failed messages can then be retried with `retryMessageExecution` + */ + event MessageExecutionFailed( + bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, TeleporterMessage message + ); + + /** + * @notice Emitted when a Teleporter message is successfully executed with the + * specified destination address and message call data. This can occur either when + * the message is initially received, or on a retry attempt. + * + * Each message received can be executed successfully at most once. + */ + event MessageExecuted(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID); + + /** + * @notice Emitted when a TeleporterMessage is successfully received. + */ + event ReceiveCrossChainMessage( + bytes32 indexed messageID, + bytes32 indexed sourceBlockchainID, + address indexed deliverer, + address rewardRedeemer, + TeleporterMessage message + ); + + /** + * @notice Emitted when a receipt is marked as received on the source chain that sent the + * corresponding Teleporter message. + */ + event ReceiptReceived( + bytes32 indexed messageID, + bytes32 indexed destinationBlockchainID, + address indexed relayerRewardAddress, + TeleporterFeeInfo feeInfo + ); + + /** + * @notice Emitted when an account redeems accumulated relayer rewards. + */ + event RelayerRewardsRedeemed(address indexed redeemer, address indexed asset, uint256 amount); + + /** + * @notice Called by transactions to initiate the sending of a cross-chain message. + * @return The message ID of the newly sent message. + */ + function sendCrossChainMessage( + TeleporterMessageInput calldata messageInput + ) external returns (bytes32); + + /** + * @notice Called by transactions to retry the sending of a cross-chain message. + * + * @dev Retriggers the sending of a message previously emitted by sendCrossChainMessage that has not yet been acknowledged + * with a receipt from the destination chain. This may be necessary in the unlikely event that less than the required + * threshold of stake weight successfully inserted the message in their messages DB at the time of the first submission. + * The message is checked to have already been previously submitted by comparing its message hash against those kept in + * state until a receipt is received for the message. + */ + function retrySendCrossChainMessage( + TeleporterMessage calldata message + ) external; + + /** + * @notice Adds the additional fee amount to the amount to be paid to the relayer that delivers + * the given message ID to the destination chain. + * + * @dev The fee token address must be the same asset type as the fee asset specified in the original + * call to sendCrossChainMessage. Reverts if the message doesn't exist or there is already + * receipt of delivery of the message. + */ + function addFeeAmount( + bytes32 messageID, + address feeTokenAddress, + uint256 additionalFeeAmount + ) external; + + /** + * @notice Receives a cross-chain message, and marks the `relayerRewardAddress` for fee reward for a successful delivery. + * + * @dev The message specified by `messageIndex` must be provided at that index in the access list storage slots of the transaction, + * and is verified in the precompile predicate. + */ + function receiveCrossChainMessage(uint32 messageIndex, address relayerRewardAddress) external; + + /** + * @notice Retries the execution of a previously delivered message by verifying the payload matches + * the hash of the payload originally delivered, and calling the destination address again. + * + * @dev Intended to be used if message excution failed on initial delivery of the Teleporter message. + * For example, this may occur if the original required gas limit was not sufficient for the message + * execution, or if the destination address did not contain a contract, but a compatible contract + * was later deployed to that address. Messages are ensured to be successfully executed at most once. + */ + function retryMessageExecution( + bytes32 sourceBlockchainID, + TeleporterMessage calldata message + ) external; + + /** + * @notice Sends the receipts for the given `messageIDs`. + * + * @dev Sends the specified message receipts in a new message (with an empty payload) back to the source chain. + * This is intended for use in sending receipts that have not been sent in a timely manner by the standard + * receipt delivery mechanism. + * @return The message ID of the newly sent message. + */ + function sendSpecifiedReceipts( + bytes32 sourceBlockchainID, + bytes32[] calldata messageIDs, + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external returns (bytes32); + + /** + * @notice Sends any fee amount rewards for the given fee asset out to the caller. + */ + function redeemRelayerRewards( + address feeTokenAddress + ) external; + + /** + * @notice Gets the hash of a given message stored in the EVM state, if the message exists. + * @return The message hash + */ + function getMessageHash( + bytes32 messageID + ) external view returns (bytes32); + + /** + * @notice Checks whether or not the given message has been received by this chain. + * @return Boolean representing if the given message has been received. + */ + function messageReceived( + bytes32 messageID + ) external view returns (bool); + + /** + * @notice Returns the address the relayer reward should be sent to on the source chain + * for a given message, assuming that the message has already been delivered. + * @return The relayer reward address for the given message. + */ + function getRelayerRewardAddress( + bytes32 messageID + ) external view returns (address); + + /** + * @notice Gets the current reward amount of a given fee asset that is redeemable by the given relayer. + * @return The amount of the fee asset redeemable by the specified relayer. + */ + function checkRelayerRewardAmount( + address relayer, + address feeTokenAddress + ) external view returns (uint256); + + /** + * @notice Gets the fee token address and amount for a given sent message. + * @return The fee token address and fee amount for a the given sent message ID. + * If the message ID is not found, zero address and amount values are returned. + */ + function getFeeInfo( + bytes32 messageID + ) external view returns (address, uint256); + + /** + * @notice Gets the message ID that would currently be used for the next message sent from the contract + * instance to the given destination blockchain. + * + * @dev This message ID may never be used in the event that the next call to sendCrossChainMessage in a + * transaction uses a different destination blockchain. The current value as returned by this function will + * change with each successful call to sendCrossChainMessage. + * @return The specified message ID. + */ + function getNextMessageID( + bytes32 destinationBlockchainID + ) external view returns (bytes32); + + /** + * @notice Gets the number of receipts that are waiting to be sent to the given source chain ID. + * @return Size of the given queue. + */ + function getReceiptQueueSize( + bytes32 sourceBlockchainID + ) external view returns (uint256); + + /** + * @notice Gets the receipt at the given index in the queue for the given source chain ID. + * @return The receipt requested. + */ + function getReceiptAtIndex( + bytes32 sourceBlockchainID, + uint256 index + ) external view returns (TeleporterMessageReceipt memory); +} diff --git a/icm-contracts/contracts/teleporter/ITeleporterReceiver.sol b/icm-contracts/contracts/teleporter/ITeleporterReceiver.sol new file mode 100644 index 000000000..eddf6076d --- /dev/null +++ b/icm-contracts/contracts/teleporter/ITeleporterReceiver.sol @@ -0,0 +1,26 @@ +// (c) 2022-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * @dev Interface that cross-chain applications must implement to receive messages from Teleporter. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface ITeleporterReceiver { + /** + * @dev Called by TeleporterMessenger on the receiving chain. + * + * @param sourceBlockchainID is provided by the TeleporterMessenger contract. + * @param originSenderAddress is provided by the TeleporterMessenger contract. + * @param message is the TeleporterMessage payload set by the sender. + */ + function receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes calldata message + ) external; +} diff --git a/icm-contracts/contracts/teleporter/README.md b/icm-contracts/contracts/teleporter/README.md new file mode 100644 index 000000000..5ca148813 --- /dev/null +++ b/icm-contracts/contracts/teleporter/README.md @@ -0,0 +1,192 @@ +# ICM Protocol + +- [Overview](#overview) +- [Data Flow](#data-flow) +- [Properties](#properties) +- [Fees](#fees) +- [Message Receipts and Fee Redemption](#message-receipts-and-fee-redemption) +- [Required Interface](#required-interface) +- [Message Delivery and Execution](#message-delivery-and-execution) +- [Resending a Message](#resending-a-message) +- [TeleporterMessenger Contract Deployment](#teleportermessenger-contract-deployment) +- [Deployed Addresses](#deployed-addresses) +- [A Note on Versioning](#a-note-on-versioning) +- [Upgradability](#upgradability) +- [Deploy TeleporterMessenger to an L1](#deploy-teleportermessenger-to-an-avalanche-l1) +- [Deploy TeleporterRegistry to an L1](#deploy-teleporterregistry-to-an-avalanche-l1) +- [Verify a Deployment of TeleporterMessenger](#verify-a-deployment-of-teleportermessenger) + +## Overview + +`TeleporterMessenger` is a smart contract that serves as the interface for ICM contracts to [Avalanche Interchain Messaging (ICM)](https://build.avax.network/academy/interchain-messaging/04-icm-basics/01-icm-basics). It provides a mechanism to asynchronously invoke smart contract functions on other EVM L1s within Avalanche. `TeleporterMessenger` provides a handful of useful features to ICM, such as specifying relayer incentives for message delivery, replay protection, message delivery and execution retries, and a standard interface for sending and receiving messages within a dApp deployed across multiple Avalanche L1s. + +The `TeleporterMessenger` contract is a user-friendly interface to ICM, aimed at dApp developers. All of the message signing and verification is abstracted away from developers. Instead, developers simply call `sendCrossChainMessage` on the `TeleporterMessenger` contract to send a message invoking a smart contract on another Avalanche L1, and implement the `ITeleporterReceiver` interface to receive messages on the destination Avalanche L1. `TeleporterMessenger` handles all of the ICM message construction and sending, as well as the message delivery and execution. + +To get started with using `TeleporterMessenger`, see [How to Deploy ICM Enabled Avalanche L1s on a Local Network](https://build.avax.network/docs/tooling/cross-chain/teleporter-local-network) + +The `ITeleporterMessenger` interface provides two primary methods: + +- `sendCrossChainMessage`: called by contracts on the origin chain to initiate the sending of a message to a contract on another EVM instance. +- `receiveCrossChainMessage`: called by cross-chain relayers on the destination chain to deliver signed messages to the destination EVM instance. + +The `ITeleporterReceiver` interface provides a single method. All contracts that wish to receive ICM messages on the destination chain must implement this interface: + +- `receiveTeleporterMessage`: called by `TeleporterMessenger` on the destination chain to deliver a message to the destination contract. + +> Note: If a contract does not implement `ITeleporterReceiver`, but instead implements [fallback](https://docs.soliditylang.org/en/latest/contracts.html#fallback-function), the fallback function will be called when `TeleporterMessenger` attempts to perform message execution. The message execution is marked as failed if the fallback function reverts, otherwise it is marked as successfully executed. + +## Data Flow + +
+ +
+ +## Properties + +TeleporterMessenger provides a handful of useful properties to cross-chain applications that ICM messages do not provide by default. These include: + +1. Replay protection: `TeleporterMessenger` ensures that a cross-chain message is not delivered multiple times. +2. Retries: In certain edge cases when there is significant validator churn, it is possible for an ICM Message to be dropped before a valid aggregate signature is created for it. `TeleporterMessenger` ensures that messages can still be delivered even in this event by allowing for retries of previously submitted messages. +3. Relay incentivization: `TeleporterMessenger` provides a mechanism for messages to optionally incentivize relayers to perform the necessary signature aggregation and pay the transaction fee to broadcast the signed message on the destination chain. +4. Allowed relayers: `TeleporterMessenger` allows users to specify a list of `allowedRelayerAddresses`, where only the specified addresses can relay and deliver the `TeleporterMessenger` message. Leaving this list empty allows all relayers to deliver. +5. Message execution: `TeleporterMessenger` enables cross-chain messages to have direct effect on their destination chain by using `evm.Call()` to invoke the `receiveTeleporterMessage` function of destination contracts that implement the `ITeleporterReceiver` interface. + +## Fees + +Fees can be paid on a per message basis by specifing the ERC20 asset and amount to be used to incentivize a relayer to deliver the message in the call to `sendCrossChainMessage`. The fee amount is transferred into the control of `TeleporterMessenger` (i.e. locked) before the ICM message is sent. `TeleporterMessenger` tracks the fee amount for each message ID it creates. When it subsequently receives a message back from the destination chain of the original message, the new message will have a list of receipts identifying the relayer that delivered the given message ID. At this point, the fee amount originally locked by `TeleporterMessenger` for the given message will be redeemable by the relayer identified in the receipt. If the initial fee amount was not sufficient to incentivize a relayer, it can be added to by using `addFeeAmount`. + +### Message Receipts and Fee Redemption + +In order to confirm delivery of a `TeleporterMessenger` message from a source chain to a destination chain, a receipt is included in the next `TeleporterMessenger` message sent in the opposite direction, from the destination chain back to the source chain. This receipt contains the message ID of the original message, as well as the reward address that the delivering relayer specified. That reward address is then able to redeem the corresponding reward on the original chain by calling `redeemRelayerRewards`. The following example illustrates this flow: + +- A `TeleporterMessenger` message is sent from Chain A to Chain B, with a relayer incentive of `10` `USDC`. This message is assigned the ID `1` by the `TeleporterMessenger` contract on Chain A. + - On Chain A, this is done by calling `sendCrossChainMessage`, and providing the `USDC` contract address and amount in the function call. +- A relayer delivers the message on Chain B by calling `receiveCrossChainMessage` and providing its address, `0x123...` +- The `TeleporterMessenger` contract on Chain B stores the relayer address in a receipt for the message ID. +- Some time later, a separate `TeleporterMessenger` message is sent from Chain B to Chain A. The `TeleporterMessenger` contract on Chain B includes the receipt for the original message in this new message. +- When this new message is delivered on Chain A, the `TeleporterMessenger` contract on Chain A reads the receipt and attributes the rewards for delivering the original message (message ID `1`) to the address `0x123...`. +- Address `0x123...` may now call `redeemRelayerRewards` on Chain A, which transfers the `10` `USDC` to its address. If it tries to do this before the receipt is received on Chain A, the call will fail. + +It is possible for receipts to get "stuck" on the destination chain in the event that `TeleporterMessenger` traffic between two chains is skewed in one direction. In such a scenario, incoming messages on one chain may cause the rate at which receipts are generated to outpace the rate at which they are sent back to the other chain. To mitigate this, the method `sendSpecifiedReceipts` can be called to immediately send the receipts associated with the given message IDs back to the original chain. + +## Required Interface + +`TeleporterMessenger` messages are delivered by calling the `receiveTeleporterMessage` function defined by the `ITeleporterReceiver` interface. Contracts must implement this interface in order to be able to receive messages. The first two parameters of `receiveTeleporterMessage` identify the original sender of the given message on the origin chain and are set by the `TeleporterMessenger`. The third parameter to `receiveTeleporterMessage`, is the raw message payload. Applications using `TeleporterMessenger` are responsible for defining the exact format of this payload in a way that can be decoded on the receiving end. For example, applications may encode an action enum value along with the target method parameters on the sending side, then decode this data and route to the target method within `receiveTeleporterMessage`. See `ERC20Bridge.sol` for an example of this approach. + +## Message Delivery and Execution + +`TeleporterMessenger` is able to ensure that messages are considered delivered even if their execution fails (i.e. reverts) by using `evm.Call()` with a pre-defined gas limit to execute the message payload. This gas limit is specified by each message in the call to `sendCrossChainMessage`. Relayers must provide at least enough gas for the sub-call in addition to the standard gas used by a call to `receiveCrossChainMessage`. In the event that a message execution runs out of gas or reverts for any other reason, the hash of the message payload is stored by the receiving `TeleporterMessenger` contract instance. This allows for the message execution to be retried in the future, with possibly a higher gas limit by calling `retryMessageExecution`. Importantly, a message is still considered delivered on its destination chain even if its execution fails. This allows the relayer of the message to redeem their reward for deliverying the message, because they have no control on whether or not its execution will succeed or not so long as they provide sufficient gas to meet the specified `requiredGasLimit`. + +Note that due to [EIP-150](https://eips.ethereum.org/EIPS/eip-150), the lesser of 63/64ths of the remaining gas and the `requiredGasLimit` will be provided to the code executed using `evm.Call()`. This creates an edge case where sufficient gas is provided by the relayer at time of the `requiredGasLimit` check, but less than the `requiredGasLimit` is provided for the message execution. In such a case, the message execution may fail due to having less than the `requiredGasLimit` available, but the message would still be considered received. Such a case is only possible if the remaining 1/64th of the `requiredGasLimit` is sufficient for executing the remaining logic of `receiveCrossChainMessage` so that the top level transaction does not also revert. Based on the current implementation, a message must have a `requiredGasLimit` of over 1,200,000 gas for this to be possible. In order to avoid this case entirely, it is recommended for applications sending `TeleporterMessenger` messages to add a buffer to the `requiredGasLimit` such that 63/64ths of the value passed is sufficient for the message execution. + +## Resending a Message + +If the sending Avalanche L1's validator set changes, then it's possible for the receiving Avalanche L1 to reject the underlying ICM message due to insufficient signing stake. For example, suppose L1 A has 5 validators with equal stake weight who all sign a `TeleporterMessenger` message sent to L1 B. 100% of L1 A's stake has signed the message. Also suppose L1 B requires 67% of the sending L1's stake to have signed a given ICM message in order for it to be accepted. Before the message can be delivered, however, 5 _more_ validators are added to L1 A's validator set (all with the same stake weight as the original validators), meaning that the `TeleporterMessenger` message was signed by _only 50%_ of L1 A's stake. L1 B will reject this message. + +Once sent on chain, ICM messages cannot be re-signed by a new validator set in such a scenario. Teleporter, however, does support re-signing via the function `retrySendCrossChainMessage`, which can be called for any message that has not been acknowledged as delivered to its destination. Under the hood, this packages the `TeleporterMessenger` message into a brand new ICM message that is re-signed by the current validator set. + +## TeleporterMessenger Contract Deployment + +**Do not deploy the `TeleporterMessenger` contract using `forge create`**. The `TeleporterMessenger` contract must be deployed to the same contract address on every chain. To achieve this, the contract can be deployed using a static transaction that uses Nick's method as documented in [this guide](https://github.com/ava-labs/icm-contracts/blob/main/utils/contract-deployment/README.md). Alternatively, if creating a new L1, the contract can be pre-allocated with the proper address and state in the new chain's [genesis file](https://build.avax.network/docs/virtual-machines/custom-precompiles#setting-the-genesis-allocation). + +As an example, to include `TeleporterMessenger` `v1.0.0` in the genesis file, include the following values in the `alloc` settings, as documented at the link above. The `storage` values included below correspond to the two contract values that are initialized as part of the default constructor of `TeleporterMessenger`. These are the `ReentrancyGuard` values set in this [abstract contract](https://github.com/ava-labs/icm-contracts/blob/main/contracts/utilities/ReentrancyGuards.sol). Future versions of `TeleporterMessenger` may require different storage value initializations. +```json +"alloc": { + "0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c8063a8898181116100c3578063df20e8bc1161007c578063df20e8bc1461033b578063e69d606a1461034e578063e6e67bd5146103b6578063ebc3b1ba146103f2578063ecc7042814610415578063fc2d61971461041e57600080fd5b8063a8898181146102b2578063a9a85614146102c5578063b771b3bc146102d8578063c473eef8146102e6578063ccb5f8091461031f578063d127dc9b1461033257600080fd5b8063399b77da11610115578063399b77da1461021957806362448850146102395780638245a1b01461024c578063860a3b061461025f578063892bf4121461027f5780638ac0fd041461029f57600080fd5b80630af5b4ff1461015257806322296c3a1461016d5780632bc8b0bf146101825780632ca40f55146101955780632e27c223146101ee575b600080fd5b61015a610431565b6040519081526020015b60405180910390f35b61018061017b366004612251565b610503565b005b61015a61019036600461226e565b6105f8565b6101e06101a336600461226e565b6005602090815260009182526040918290208054835180850190945260018201546001600160a01b03168452600290910154918301919091529082565b604051610164929190612287565b6102016101fc36600461226e565b610615565b6040516001600160a01b039091168152602001610164565b61015a61022736600461226e565b60009081526005602052604090205490565b61015a6102473660046122ae565b61069e565b61018061025a366004612301565b6106fc565b61015a61026d36600461226e565b60066020526000908152604090205481565b61029261028d366004612335565b6108a7565b6040516101649190612357565b6101806102ad366004612377565b6108da565b61015a6102c03660046123af565b610b19565b61015a6102d3366004612426565b610b5c565b6102016005600160991b0181565b61015a6102f43660046124be565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205490565b61018061032d3660046124f7565b610e03565b61015a60025481565b61015a61034936600461226e565b61123d565b61039761035c36600461226e565b600090815260056020908152604091829020825180840190935260018101546001600160a01b03168084526002909101549290910182905291565b604080516001600160a01b039093168352602083019190915201610164565b6103dd6103c436600461226e565b6004602052600090815260409020805460019091015482565b60408051928352602083019190915201610164565b61040561040036600461226e565b611286565b6040519015158152602001610164565b61015a60035481565b61018061042c36600461251e565b61129c565b600254600090806104fe576005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104a59190612564565b9050806104cd5760405162461bcd60e51b81526004016104c49061257d565b60405180910390fd5b600281905560405181907f1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b10490600090a25b919050565b3360009081526009602090815260408083206001600160a01b0385168452909152902054806105855760405162461bcd60e51b815260206004820152602860248201527f54656c65706f727465724d657373656e6765723a206e6f2072657761726420746044820152676f2072656465656d60c01b60648201526084016104c4565b3360008181526009602090815260408083206001600160a01b03871680855290835281842093909355518481529192917f3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88910160405180910390a36105f46001600160a01b03831633836114f7565b5050565b600081815260046020526040812061060f9061155f565b92915050565b6000818152600760205260408120546106825760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f74604482015268081c9958d95a5d995960ba1b60648201526084016104c4565b506000908152600860205260409020546001600160a01b031690565b60006001600054146106c25760405162461bcd60e51b81526004016104c4906125c4565b60026000556106f16106d383612804565b833560009081526004602052604090206106ec90611572565b61167c565b600160005592915050565b60016000541461071e5760405162461bcd60e51b81526004016104c4906125c4565b6002600081815590546107379060408401358435610b19565b6000818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b03168452600290910154838301529081019190915280519192509061079f5760405162461bcd60e51b81526004016104c4906128a7565b6000836040516020016107b29190612b42565b60408051601f19818403018152919052825181516020830120919250146107eb5760405162461bcd60e51b81526004016104c490612b55565b8360400135837f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8868560200151604051610826929190612b9e565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb90610858908490600401612c23565b6020604051808303816000875af1158015610877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089b9190612564565b50506001600055505050565b604080518082019091526000808252602082015260008381526004602052604090206108d390836118bc565b9392505050565b6001600054146108fc5760405162461bcd60e51b81526004016104c4906125c4565b600260005560018054146109225760405162461bcd60e51b81526004016104c490612c36565b60026001558061098c5760405162461bcd60e51b815260206004820152602f60248201527f54656c65706f727465724d657373656e6765723a207a65726f2061646469746960448201526e1bdb985b0819995948185b5bdd5b9d608a1b60648201526084016104c4565b6001600160a01b0382166109b25760405162461bcd60e51b81526004016104c490612c7b565b6000838152600560205260409020546109dd5760405162461bcd60e51b81526004016104c4906128a7565b6000838152600560205260409020600101546001600160a01b03838116911614610a6f5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642066656560448201527f20617373657420636f6e7472616374206164647265737300000000000000000060648201526084016104c4565b6000610a7b8383611981565b600085815260056020526040812060020180549293508392909190610aa1908490612ce5565b909155505060008481526005602052604090819020905185917fc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e191610b03916001019081546001600160a01b0316815260019190910154602082015260400190565b60405180910390a2505060018080556000555050565b60408051306020820152908101849052606081018390526080810182905260009060a0016040516020818303038152906040528051906020012090509392505050565b6000600160005414610b805760405162461bcd60e51b81526004016104c4906125c4565b60026000818155905490866001600160401b03811115610ba257610ba2612607565b604051908082528060200260200182016040528015610be757816020015b6040805180820190915260008082526020820152815260200190600190039081610bc05790505b5090508660005b81811015610d6c5760008a8a83818110610c0a57610c0a612cf8565b90506020020135905060006007600083815260200190815260200160002054905080600003610c8a5760405162461bcd60e51b815260206004820152602660248201527f54656c65706f727465724d657373656e6765723a2072656365697074206e6f7460448201526508199bdd5b9960d21b60648201526084016104c4565b610c958d8783610b19565b8214610d095760405162461bcd60e51b815260206004820152603a60248201527f54656c65706f727465724d657373656e6765723a206d6573736167652049442060448201527f6e6f742066726f6d20736f7572636520626c6f636b636861696e00000000000060648201526084016104c4565b6000828152600860209081526040918290205482518084019093528383526001600160a01b03169082018190528651909190879086908110610d4d57610d4d612cf8565b602002602001018190525050505080610d6590612d0e565b9050610bee565b506040805160c0810182528b815260006020820152610df0918101610d96368b90038b018b612d27565b8152602001600081526020018888808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250938552505060408051928352602080840190915290920152508361167c565b60016000559a9950505050505050505050565b6001805414610e245760405162461bcd60e51b81526004016104c490612c36565b60026001556040516306f8253560e41b815263ffffffff8316600482015260009081906005600160991b0190636f82535090602401600060405180830381865afa158015610e76573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e9e9190810190612da3565b9150915080610f015760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642077617260448201526870206d65737361676560b81b60648201526084016104c4565b60208201516001600160a01b03163014610f785760405162461bcd60e51b815260206004820152603260248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206f726960448201527167696e2073656e646572206164647265737360701b60648201526084016104c4565b60008260400151806020019051810190610f929190612f40565b90506000610f9e610431565b90508082604001511461100d5760405162461bcd60e51b815260206004820152603160248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206465736044820152701d1a5b985d1a5bdb8818da185a5b881251607a1b60648201526084016104c4565b8351825160009161101f918490610b19565b600081815260076020526040902054909150156110945760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f727465724d657373656e6765723a206d65737361676520616c7260448201526c1958591e481c9958d95a5d9959609a1b60648201526084016104c4565b6110a2338460a00151611ae9565b6111005760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20756e617574686f72697a6560448201526832103932b630bcb2b960b91b60648201526084016104c4565b61110e818460000151611b61565b6001600160a01b0386161561114557600081815260086020526040902080546001600160a01b0319166001600160a01b0388161790555b60c08301515160005b81811015611192576111828488600001518760c00151848151811061117557611175612cf8565b6020026020010151611bd3565b61118b81612d0e565b905061114e565b50604080518082018252855181526001600160a01b038916602080830191909152885160009081526004909152919091206111cc91611cfb565b336001600160a01b03168660000151837f292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e348a8860405161120d929190613150565b60405180910390a460e0840151511561122f5761122f82876000015186611d57565b505060018055505050505050565b600254600090806112605760405162461bcd60e51b81526004016104c49061257d565b600060035460016112719190612ce5565b905061127e828583610b19565b949350505050565b600081815260076020526040812054151561060f565b60018054146112bd5760405162461bcd60e51b81526004016104c490612c36565b60026001819055546000906112d59084908435610b19565b600081815260066020526040902054909150806113045760405162461bcd60e51b81526004016104c4906128a7565b80836040516020016113169190612b42565b60405160208183030381529060405280519060200120146113495760405162461bcd60e51b81526004016104c490612b55565b600061135b6080850160608601612251565b6001600160a01b03163b116113cf5760405162461bcd60e51b815260206004820152603460248201527f54656c65706f727465724d657373656e6765723a2064657374696e6174696f6e604482015273206164647265737320686173206e6f20636f646560601b60648201526084016104c4565b604051849083907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c90600090a360008281526006602090815260408083208390558691611420918701908701612251565b61142d60e0870187613174565b60405160240161144094939291906131ba565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b179052905060006114886114816080870160608801612251565b5a84611e8a565b9050806114eb5760405162461bcd60e51b815260206004820152602b60248201527f54656c65706f727465724d657373656e6765723a20726574727920657865637560448201526a1d1a5bdb8819985a5b195960aa1b60648201526084016104c4565b50506001805550505050565b6040516001600160a01b03831660248201526044810182905261155a90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611ea4565b505050565b8054600182015460009161060f916131e5565b6060600061158960056115848561155f565b611f76565b9050806000036115d85760408051600080825260208201909252906115d0565b60408051808201909152600080825260208201528152602001906001900390816115a95790505b509392505050565b6000816001600160401b038111156115f2576115f2612607565b60405190808252806020026020018201604052801561163757816020015b60408051808201909152600080825260208201528152602001906001900390816116105790505b50905060005b828110156115d05761164e85611f8c565b82828151811061166057611660612cf8565b60200260200101819052508061167590612d0e565b905061163d565b600080611687610431565b9050600060036000815461169a90612d0e565b919050819055905060006116b383876000015184610b19565b90506000604051806101000160405280848152602001336001600160a01b031681526020018860000151815260200188602001516001600160a01b0316815260200188606001518152602001886080015181526020018781526020018860a00151815250905060008160405160200161172c91906131f8565b60405160208183030381529060405290506000808960400151602001511115611794576040890151516001600160a01b031661177a5760405162461bcd60e51b81526004016104c490612c7b565b604089015180516020909101516117919190611981565b90505b6040805180820182528a820151516001600160a01b039081168252602080830185905283518085018552865187830120815280820184815260008a815260058452869020915182555180516001830180546001600160a01b03191691909516179093559101516002909101558a51915190919086907f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df890611838908890869061320b565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb9061186a908690600401612c23565b6020604051808303816000875af1158015611889573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ad9190612564565b50939998505050505050505050565b60408051808201909152600080825260208201526118d98361155f565b82106119315760405162461bcd60e51b815260206004820152602160248201527f5265636569707451756575653a20696e646578206f7574206f6620626f756e646044820152607360f81b60648201526084016104c4565b8260020160008385600001546119479190612ce5565b81526020808201929092526040908101600020815180830190925280548252600101546001600160a01b0316918101919091529392505050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156119ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ee9190612564565b9050611a056001600160a01b038516333086612058565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015611a4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a709190612564565b9050818111611ad65760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016104c4565b611ae082826131e5565b95945050505050565b60008151600003611afc5750600161060f565b815160005b81811015611b5657846001600160a01b0316848281518110611b2557611b25612cf8565b60200260200101516001600160a01b031603611b465760019250505061060f565b611b4f81612d0e565b9050611b01565b506000949350505050565b80600003611bc15760405162461bcd60e51b815260206004820152602760248201527f54656c65706f727465724d657373656e6765723a207a65726f206d657373616760448201526665206e6f6e636560c81b60648201526084016104c4565b60009182526007602052604090912055565b6000611be484848460000151610b19565b6000818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b031684526002909101548383015290810191909152805191925090611c3b575050505050565b60008281526005602090815260408083208381556001810180546001600160a01b03191690556002018390558382018051830151878401516001600160a01b0390811686526009855283862092515116855292528220805491929091611ca2908490612ce5565b9250508190555082602001516001600160a01b031684837fd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf578460200151604051611cec919061321e565b60405180910390a45050505050565b6001820180548291600285019160009182611d1583612d0e565b90915550815260208082019290925260400160002082518155910151600190910180546001600160a01b0319166001600160a01b039092169190911790555050565b80608001515a1015611db95760405162461bcd60e51b815260206004820152602560248201527f54656c65706f727465724d657373656e6765723a20696e73756666696369656e604482015264742067617360d81b60648201526084016104c4565b80606001516001600160a01b03163b600003611dda5761155a838383612096565b602081015160e0820151604051600092611df892869260240161323e565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b17905260608301516080840151919250600091611e3d919084611e8a565b905080611e5657611e4f858585612096565b5050505050565b604051849086907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c90600090a35050505050565b60008060008084516020860160008989f195945050505050565b6000611ef9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661210b9092919063ffffffff16565b80519091501561155a5780806020019051810190611f179190613268565b61155a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016104c4565b6000818310611f8557816108d3565b5090919050565b604080518082019091526000808252602082015281546001830154819003611ff65760405162461bcd60e51b815260206004820152601960248201527f5265636569707451756575653a20656d7074792071756575650000000000000060448201526064016104c4565b60008181526002840160208181526040808420815180830190925280548252600180820180546001600160a01b03811685870152888852959094529490556001600160a01b031990921690559061204e908390612ce5565b9093555090919050565b6040516001600160a01b03808516602483015283166044820152606481018290526120909085906323b872dd60e01b90608401611523565b50505050565b806040516020016120a791906131f8565b60408051601f1981840301815282825280516020918201206000878152600690925291902055829084907f4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c985906120fe9085906131f8565b60405180910390a3505050565b606061127e848460008585600080866001600160a01b031685876040516121329190613283565b60006040518083038185875af1925050503d806000811461216f576040519150601f19603f3d011682016040523d82523d6000602084013e612174565b606091505b509150915061218587838387612190565b979650505050505050565b606083156121ff5782516000036121f8576001600160a01b0385163b6121f85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104c4565b508161127e565b61127e83838151156122145781518083602001fd5b8060405162461bcd60e51b81526004016104c49190612c23565b6001600160a01b038116811461224357600080fd5b50565b80356104fe8161222e565b60006020828403121561226357600080fd5b81356108d38161222e565b60006020828403121561228057600080fd5b5035919050565b828152606081016108d3602083018480516001600160a01b03168252602090810151910152565b6000602082840312156122c057600080fd5b81356001600160401b038111156122d657600080fd5b820160e081850312156108d357600080fd5b600061010082840312156122fb57600080fd5b50919050565b60006020828403121561231357600080fd5b81356001600160401b0381111561232957600080fd5b61127e848285016122e8565b6000806040838503121561234857600080fd5b50508035926020909101359150565b815181526020808301516001600160a01b0316908201526040810161060f565b60008060006060848603121561238c57600080fd5b83359250602084013561239e8161222e565b929592945050506040919091013590565b6000806000606084860312156123c457600080fd5b505081359360208301359350604090920135919050565b60008083601f8401126123ed57600080fd5b5081356001600160401b0381111561240457600080fd5b6020830191508360208260051b850101111561241f57600080fd5b9250929050565b60008060008060008086880360a081121561244057600080fd5b8735965060208801356001600160401b038082111561245e57600080fd5b61246a8b838c016123db565b90985096508691506040603f198401121561248457600080fd5b60408a01955060808a013592508083111561249e57600080fd5b50506124ac89828a016123db565b979a9699509497509295939492505050565b600080604083850312156124d157600080fd5b82356124dc8161222e565b915060208301356124ec8161222e565b809150509250929050565b6000806040838503121561250a57600080fd5b823563ffffffff811681146124dc57600080fd5b6000806040838503121561253157600080fd5b8235915060208301356001600160401b0381111561254e57600080fd5b61255a858286016122e8565b9150509250929050565b60006020828403121561257657600080fd5b5051919050565b60208082526027908201527f54656c65706f727465724d657373656e6765723a207a65726f20626c6f636b636040820152661a185a5b88125160ca1b606082015260800190565b60208082526023908201527f5265656e7472616e63794775617264733a2073656e646572207265656e7472616040820152626e637960e81b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561263f5761263f612607565b60405290565b60405160c081016001600160401b038111828210171561263f5761263f612607565b60405161010081016001600160401b038111828210171561263f5761263f612607565b604051601f8201601f191681016001600160401b03811182821017156126b2576126b2612607565b604052919050565b6000604082840312156126cc57600080fd5b6126d461261d565b905081356126e18161222e565b808252506020820135602082015292915050565b60006001600160401b0382111561270e5761270e612607565b5060051b60200190565b600082601f83011261272957600080fd5b8135602061273e612739836126f5565b61268a565b82815260059290921b8401810191818101908684111561275d57600080fd5b8286015b848110156127815780356127748161222e565b8352918301918301612761565b509695505050505050565b60006001600160401b038211156127a5576127a5612607565b50601f01601f191660200190565b600082601f8301126127c457600080fd5b81356127d26127398261278c565b8181528460208386010111156127e757600080fd5b816020850160208301376000918101602001919091529392505050565b600060e0823603121561281657600080fd5b61281e612645565b8235815261282e60208401612246565b602082015261284036604085016126ba565b60408201526080830135606082015260a08301356001600160401b038082111561286957600080fd5b61287536838701612718565b608084015260c085013591508082111561288e57600080fd5b5061289b368286016127b3565b60a08301525092915050565b60208082526026908201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f7460408201526508199bdd5b9960d21b606082015260800190565b6000808335601e1984360301811261290457600080fd5b83016020810192503590506001600160401b0381111561292357600080fd5b8060051b360382131561241f57600080fd5b8183526000602080850194508260005b858110156129735781356129588161222e565b6001600160a01b031687529582019590820190600101612945565b509495945050505050565b6000808335601e1984360301811261299557600080fd5b83016020810192503590506001600160401b038111156129b457600080fd5b8060061b360382131561241f57600080fd5b8183526000602080850194508260005b858110156129735781358752828201356129ef8161222e565b6001600160a01b03168784015260409687019691909101906001016129d6565b6000808335601e19843603018112612a2657600080fd5b83016020810192503590506001600160401b03811115612a4557600080fd5b80360382131561241f57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000610100823584526020830135612a948161222e565b6001600160a01b0316602085015260408381013590850152612ab860608401612246565b6001600160a01b0316606085015260808381013590850152612add60a08401846128ed565b8260a0870152612af08387018284612935565b92505050612b0160c084018461297e565b85830360c0870152612b148382846129c6565b92505050612b2560e0840184612a0f565b85830360e0870152612b38838284612a54565b9695505050505050565b6020815260006108d36020830184612a7d565b60208082526029908201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206d65736040820152680e6c2ceca40d0c2e6d60bb1b606082015260800190565b606081526000612bb16060830185612a7d565b90506108d3602083018480516001600160a01b03168252602090810151910152565b60005b83811015612bee578181015183820152602001612bd6565b50506000910152565b60008151808452612c0f816020860160208601612bd3565b601f01601f19169290920160200192915050565b6020815260006108d36020830184612bf7565b60208082526025908201527f5265656e7472616e63794775617264733a207265636569766572207265656e7460408201526472616e637960d81b606082015260800190565b60208082526034908201527f54656c65706f727465724d657373656e6765723a207a65726f2066656520617360408201527373657420636f6e7472616374206164647265737360601b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8082018082111561060f5761060f612ccf565b634e487b7160e01b600052603260045260246000fd5b600060018201612d2057612d20612ccf565b5060010190565b600060408284031215612d3957600080fd5b6108d383836126ba565b80516104fe8161222e565b600082601f830112612d5f57600080fd5b8151612d6d6127398261278c565b818152846020838601011115612d8257600080fd5b61127e826020830160208701612bd3565b805180151581146104fe57600080fd5b60008060408385031215612db657600080fd5b82516001600160401b0380821115612dcd57600080fd5b9084019060608287031215612de157600080fd5b604051606081018181108382111715612dfc57612dfc612607565b604052825181526020830151612e118161222e565b6020820152604083015182811115612e2857600080fd5b612e3488828601612d4e565b6040830152509350612e4b91505060208401612d93565b90509250929050565b600082601f830112612e6557600080fd5b81516020612e75612739836126f5565b82815260059290921b84018101918181019086841115612e9457600080fd5b8286015b84811015612781578051612eab8161222e565b8352918301918301612e98565b600082601f830112612ec957600080fd5b81516020612ed9612739836126f5565b82815260069290921b84018101918181019086841115612ef857600080fd5b8286015b848110156127815760408189031215612f155760008081fd5b612f1d61261d565b8151815284820151612f2e8161222e565b81860152835291830191604001612efc565b600060208284031215612f5257600080fd5b81516001600160401b0380821115612f6957600080fd5b908301906101008286031215612f7e57600080fd5b612f86612667565b82518152612f9660208401612d43565b602082015260408301516040820152612fb160608401612d43565b60608201526080830151608082015260a083015182811115612fd257600080fd5b612fde87828601612e54565b60a08301525060c083015182811115612ff657600080fd5b61300287828601612eb8565b60c08301525060e08301518281111561301a57600080fd5b61302687828601612d4e565b60e08301525095945050505050565b600081518084526020808501945080840160005b838110156129735781516001600160a01b031687529582019590820190600101613049565b600081518084526020808501945080840160005b83811015612973576130a8878351805182526020908101516001600160a01b0316910152565b6040969096019590820190600101613082565b60006101008251845260018060a01b0360208401511660208501526040830151604085015260608301516130fa60608601826001600160a01b03169052565b506080830151608085015260a08301518160a086015261311c82860182613035565b91505060c083015184820360c0860152613136828261306e565b91505060e083015184820360e0860152611ae08282612bf7565b6001600160a01b038316815260406020820181905260009061127e908301846130bb565b6000808335601e1984360301811261318b57600080fd5b8301803591506001600160401b038211156131a557600080fd5b60200191503681900382131561241f57600080fd5b8481526001600160a01b0384166020820152606060408201819052600090612b389083018486612a54565b8181038181111561060f5761060f612ccf565b6020815260006108d360208301846130bb565b606081526000612bb160608301856130bb565b81516001600160a01b03168152602080830151908201526040810161060f565b8381526001600160a01b0383166020820152606060408201819052600090611ae090830184612bf7565b60006020828403121561327a57600080fd5b6108d382612d93565b60008251613295818460208701612bd3565b919091019291505056fea2646970667358221220586881dd1413fe17197100ceb55646481dae802ef65d37df603c3915f51a4b6364736f6c63430008120033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "nonce": 1 + }, + "0x618FEdD9A45a8C456812ecAAE70C671c6249DfaC": { + "balance": "0x0", + "nonce": 1 + } +} +``` + +The values above are taken from the `v1.0.0` [release artifacts](https://github.com/ava-labs/icm-contracts/releases/tag/v1.0.0). The contract address, deployed bytecode, and deployer address are unique per major release. All of the other values should remain the same. + +## Deployed Addresses + +| Contract | Address | Chain | +| --------------------- | ---------------------------------------------- | ------------------------ | +| `TeleporterMessenger` | **0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf** | All chains, all networks | +| `TeleporterRegistry` | **0x7C43605E14F391720e1b37E49C78C4b03A488d98** | Mainnet C-Chain | +| `TeleporterRegistry` | **0xF86Cb19Ad8405AEFa7d09C778215D2Cb6eBfB228** | Fuji C-Chain | + +- Using [Nick's method](https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c#), `TeleporterMessenger` deploys at a universal address across all chains, varying with each `teleporter` Major release. **Compatibility exists only between same-version `TeleporterMessenger` instances.** See [TeleporterMessenger Contract Deployment](https://github.com/ava-labs/icm-contracts/blob/main/utils/contract-deployment/README.md) and [Deploy TeleporterMessenger to an Avalanche L1](#deploy-teleportermessenger-to-an-avalanche-l1) for more details. + +- `TeleporterRegistry` can be deployed to any address. See [Deploy TeleporterRegistry to an Avalanche L1](#deploy-teleporterregistry-to-an-avalanche-l1) for details. The table above enumerates the canonical registry addresses on the Mainnet and Fuji C-Chains. + +## A Note on Versioning + +Release versions follow the [semver](https://semver.org/) convention of incompatible Major releases. A new Major version is released whenever the `TeleporterMessenger` bytecode is changed, and a new version of `TeleporterMessenger` is meant to be deployed. Due to the use of Nick's method to deploy the contract to the same address on all chains (see [TeleporterMessenger Contract Deployment](https://github.com/ava-labs/icm-contracts/blob/main/utils/contract-deployment/README.md) for details), this also means that new release versions would result in different `TeleporterMessenger` contract addresses. Minor and Patch versions may pertain to contract changes that do not change the `TeleporterMessenger` bytecode, or to changes in the test frameworks, and will only be included in tags. + +## Upgradability + +`TeleporterMessenger` is a non-upgradeable contract and can not be changed once it is deployed. This provides immutability to the contracts, and ensures that the contract's behavior at each address is unchanging. However, to allow for new features and potential bug fixes, new versions of `TeleporterMessenger` can be deployed to different addresses. The [TeleporterRegistry](https://github.com/ava-labs/icm-contracts/blob/main/contracts/teleporter/registry/TeleporterRegistry.sol) is used to keep track of the deployed versions of Teleporter, and to provide a standard interface for dApps to interact with the different `TeleporterMessenger` versions. + +`TeleporterRegistry` **is not mandatory** for dApps built on top of ICM, but dApp's are recommended to leverage the registry to ensure they use the latest `TeleporterMessenger` version available. Another recommendation standard is to have a single canonical `TeleporterRegistry` for each Avalanche L1, and unlike the `TeleporterMessenger` contract, the registry does not need to be deployed to the same address on every chain. This means the registry does not need a Nick's method deployment, and can be at different contract addresses on different chains. + +For more information on the registry and how to integrate with ICM contracts, see the [Upgradability doc](https://github.com/ava-labs/icm-contracts/blob/main/contracts/teleporter/registry/README.md). + +## Deploy TeleporterMessenger to an Avalanche L1 + +From the root of the repo, the TeleporterMessenger contract can be deployed by calling + +```bash +./scripts/deploy_teleporter.sh --version --rpc-url [OPTIONS] +``` + +Required arguments: + +- `--version ` Specify the release version to deploy. These will all be of the form `v1.X.0`. Each `TeleporterMessenger` version can only send and receive messages from the **same** `TeleporterMessenger` version on another chain. You can see a list of released versions at https://github.com/ava-labs/icm-contracts/releases. +- `--rpc-url ` Specify the rpc url of the node to use. + +Options: + +- `--private-key ` Funds the deployer address with the account held by `` + +To ensure that `TeleporterMessenger` can be deployed to the same address on every EVM based chain, it uses [Nick's Method](https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c) to deploy from a static deployer address. Teleporter costs exactly `10eth` in the Avalanche L1's native gas token to deploy, which must be sent to the deployer address. + +`deploy_teleporter.sh` will send the necessary native tokens to the deployer address if it is provided with a private key for an account with sufficient funds. Alternatively, the deployer address can be funded externally. The deployer address for each version can be found by looking up the appropriate version at https://github.com/ava-labs/icm-contracts/releases and downloading `TeleporterMessenger_Deployer_Address_.txt`. + +Alternatively for new Avalanche L1s, the `TeleporterMessenger` contract can be directly included in the genesis file as documented [here](https://github.com/ava-labs/icm-contracts/blob/main/contracts/teleporter/README.md#teleporter-messenger-contract-deployment). + +## Deploy TeleporterRegistry to an Avalanche L1 + +There should only be one canonical `TeleporterRegistry` deployed for each chain, but if one does not exist, it is recommended to deploy the registry so ICM contracts can always use the most recent `TeleporterMessenger` version available. The registry does not need to be deployed to the same address on every chain, and therefore does not need a Nick's method transaction. To deploy, run the following command from the root of the repository: + +```bash +./scripts/deploy_registry.sh --version --rpc-url --private-key [OPTIONS] +``` + +Required arguments: + +- `--version ` Specify the release version to deploy. These will all be of the form `v1.X.0`. +- `--rpc-url ` Specify the rpc url of the node to use. +- `--private-key ` Funds the deployer address with the account held by `` + +`deploy_registry.sh` will deploy a new `TeleporterRegistry` contract for the intended release version, and will also have the corresponding `TeleporterMessenger` contract registered as the initial protocol version. + +## Verify a Deployment of TeleporterMessenger + +`TeleporterMessenger` can be verified on L1s using sourcify. `v1.0.0` of this repository must be checked out in order to match the source code properly. + +```bash +git checkout v1.0.0 +git submodule update --init --recursive +cd contracts + +forge verify-contract 0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf \ + src/teleporter/TeleporterMessenger.sol:TeleporterMessenger \ + --chain-id \ + --rpc-url \ + --verifier sourcify \ + --compiler-version v0.8.18+commit.87f61d96 \ + --num-of-optimizations 200 \ +``` diff --git a/icm-contracts/contracts/teleporter/ReceiptQueue.sol b/icm-contracts/contracts/teleporter/ReceiptQueue.sol new file mode 100644 index 000000000..089e4fbea --- /dev/null +++ b/icm-contracts/contracts/teleporter/ReceiptQueue.sol @@ -0,0 +1,100 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Math} from "@openzeppelin/contracts@5.0.2/utils/math/Math.sol"; +import {TeleporterMessageReceipt} from "./ITeleporterMessenger.sol"; + +/** + * @dev ReceiptQueue is a convenience library that creates a queue-like interface of + * TeleporterMessageReceipt structs. It provides FIFO properties. + * Note: All functions in this library are internal so that the library is not deployed as a contract. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +library ReceiptQueue { + // A receipt queue represents a FIFO list of receipts. + struct TeleporterMessageReceiptQueue { + // Tracks the head of the queue within the {data} mapping. + uint256 first; + // Tracks the tail of the queue within the {data} mapping. + uint256 last; + // Represents the elements in the queue. Each newly enqueue item is + // assigned an index one greater than the previous tail. + mapping(uint256 index => TeleporterMessageReceipt receipt) data; + } + + // The maximum number of receipts to include in a single message. + uint256 private constant _MAXIMUM_RECEIPT_COUNT = 5; + + // solhint-disable private-vars-leading-underscore + /** + * @dev Adds a receipt to the queue. + */ + function enqueue( + TeleporterMessageReceiptQueue storage queue, + TeleporterMessageReceipt memory receipt + ) internal { + queue.data[queue.last++] = receipt; + } + + /** + * @dev Removes the oldest outstanding receipt from the queue. + * + * Requirements: + * - The queue must be non-empty. + */ + function dequeue( + TeleporterMessageReceiptQueue storage queue + ) internal returns (TeleporterMessageReceipt memory) { + uint256 first_ = queue.first; + require(queue.last != first_, "ReceiptQueue: empty queue"); + TeleporterMessageReceipt memory receipt = queue.data[first_]; + delete queue.data[first_]; + queue.first = first_ + 1; + return receipt; + } + + /** + * @dev Returns the outstanding receipts for the given chain ID that should be included in the next message sent. + */ + function getOutstandingReceiptsToSend( + TeleporterMessageReceiptQueue storage queue + ) internal returns (TeleporterMessageReceipt[] memory) { + // Calculate the result size as the minimum of the number of receipts and maximum batch size. + uint256 resultSize = Math.min(_MAXIMUM_RECEIPT_COUNT, size(queue)); + if (resultSize == 0) { + return new TeleporterMessageReceipt[](0); + } + + TeleporterMessageReceipt[] memory receipts = new TeleporterMessageReceipt[](resultSize); + for (uint256 i; i < resultSize; ++i) { + receipts[i] = dequeue(queue); + } + return receipts; + } + + /** + * @dev Returns the number of outstanding receipts in the queue. + */ + function size( + TeleporterMessageReceiptQueue storage queue + ) internal view returns (uint256) { + return queue.last - queue.first; + } + + /** + * @dev Returns the receipt at the given index in the queue. + */ + function getReceiptAtIndex( + TeleporterMessageReceiptQueue storage queue, + uint256 index + ) internal view returns (TeleporterMessageReceipt memory) { + require(index < size(queue), "ReceiptQueue: index out of bounds"); + return queue.data[queue.first + index]; + } + // solhint-enable private-vars-leading-underscore +} diff --git a/icm-contracts/contracts/teleporter/TeleporterMessenger.sol b/icm-contracts/contracts/teleporter/TeleporterMessenger.sol new file mode 100644 index 000000000..b784f4aef --- /dev/null +++ b/icm-contracts/contracts/teleporter/TeleporterMessenger.sol @@ -0,0 +1,845 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {WarpMessage, IWarpMessenger} from "@subnet-evm/IWarpMessenger.sol"; +import { + TeleporterMessageReceipt, + TeleporterMessageInput, + TeleporterMessage, + TeleporterFeeInfo, + ITeleporterMessenger +} from "./ITeleporterMessenger.sol"; +import {ReceiptQueue} from "./ReceiptQueue.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {ITeleporterReceiver} from "./ITeleporterReceiver.sol"; +import {ReentrancyGuards} from "@utilities/ReentrancyGuards.sol"; + +/** + * @dev Implementation of the {ITeleporterMessenger} interface. + * + * This implementation is used to send messages cross chain using the IWarpMessenger precompile, + * and to receive messages sent from other chains. Teleporter contracts should be deployed through Nick's method + * of universal deployer, such that the same contract is deployed at the same address on all chains. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract TeleporterMessenger is ITeleporterMessenger, ReentrancyGuards { + using SafeERC20 for IERC20; + using ReceiptQueue for ReceiptQueue.TeleporterMessageReceiptQueue; + + /** + * @notice SentMessageInfo includes the fee information for a given message submitted + * to be sent, along with the hash of the message itself. + */ + struct SentMessageInfo { + bytes32 messageHash; + TeleporterFeeInfo feeInfo; + } + + /** + * @notice Warp precompile used for sending and receiving Warp messages. + */ + IWarpMessenger public constant WARP_MESSENGER = + IWarpMessenger(0x0200000000000000000000000000000000000005); + + /** + * @notice The blockchain ID of the chain the contract is deployed on. + * @dev Can be initialized by calling initializeBlockchainID, or will be initialized + * automatically on the first successful call to send or receive a message. + */ + bytes32 public blockchainID; + + /** + * @notice A monotonically incremented integer tracking the total number of messages sent by this TeleporterMessenger contract. + * @dev Used to provide uniqueness when generating message IDs for new messages. The first message sent will use a + * messageNonce of 1 such that the nonce value can be used to provide replay protection for a given message ID. + */ + uint256 public messageNonce; + + /** + * @notice Tracks the outstanding receipts to send back to a given chain in subsequent messages sent to that chain. + * @dev The key is the blockchain ID of the other chain, and the value is a queue of pending receipts for messages + * received from that chain. + */ + mapping(bytes32 sourceBlockchainID => ReceiptQueue.TeleporterMessageReceiptQueue receiptQueue) + public receiptQueues; + + /** + * @notice Tracks the message hash and fee information for each message sent that has yet to be acknowledged + * with a receipt. + * @dev The key is the message ID, and the value is the info for the uniquely identified message. + */ + mapping(bytes32 messageID => SentMessageInfo messageInfo) public sentMessageInfo; + + /** + * @notice Tracks the hash of messages that have been received but have never succeeded in execution. + * @dev Enables retrying of failed messages with higher gas limits. Message execution is guaranteed to + * succeed at most once. The key is the message ID, and the value is the hash of the uniquely + * identified message whose execution failed. + */ + mapping(bytes32 messageID => bytes32 messageHash) public receivedFailedMessageHashes; + + /** + * @dev Tracks the message nonce for each message that has been received. The key is the message ID, + * and the value is the nonce value that was received as a part of that message. + * Note: the `messageNonce` values are also used to determine if a given message has been received or not. + */ + mapping(bytes32 messageID => uint256 messageNonce) internal _receivedMessageNonces; + + /** + * @dev Tracks the relayer reward address for each message that has been received. + * The key is the message ID, and the value is the reward address provided by the deliverer of the message. + */ + mapping(bytes32 messageID => address relayerRewardAddress) internal _relayerRewardAddresses; + + /** + * @dev Tracks the reward amounts for a given asset able to be redeemed by a given relayer. + * The first key is the relayer reward address, the second key is the fee token contract address, + * and the value is the amount of the asset redeemable by the relayer. + */ + mapping( + address relayerRewardAddress + => mapping(address feeTokenContract => uint256 redeemableRewardAmount) + ) internal _relayerRewardAmounts; + + /** + * @dev See {ITeleporterMessenger-sendCrossChainMessage} + * + * When executed, a relayer may kick off an asynchronous event to have the validators of the + * chain create an aggregate BLS signature of the message. + * + * Emits a {SendCrossChainMessage} event when message successfully gets sent. + */ + function sendCrossChainMessage( + TeleporterMessageInput calldata messageInput + ) external senderNonReentrant returns (bytes32) { + // Get the outstanding receipts for messages that have been previously received + // from the destination chain but not yet acknowledged, and attach the receipts + // to the Teleporter message to be sent. + return _sendTeleporterMessage( + messageInput, + receiptQueues[messageInput.destinationBlockchainID].getOutstandingReceiptsToSend() + ); + } + + /** + * @dev Emits a {SendCrossChainMessage} event. + * Requirements: + * + * - `message` must have been previously sent. + * - `message` encoding must match previously sent message. + * + * @inheritdoc ITeleporterMessenger + */ + function retrySendCrossChainMessage( + TeleporterMessage calldata message + ) external senderNonReentrant { + // Calculate the message ID based on the message nonce. + // If the blockchain ID has yet to be initialized, no messages have ever been sent by + // this contract, meaning that the message to be retried will not be found in any event. + // Thus, don't need to initialize the blockchain ID here. + bytes32 messageID = + calculateMessageID(blockchainID, message.destinationBlockchainID, message.messageNonce); + + // Get the previously sent message hash. + SentMessageInfo memory existingMessageInfo = sentMessageInfo[messageID]; + // If the message hash is zero, the message was never sent. + require( + existingMessageInfo.messageHash != bytes32(0), "TeleporterMessenger: message not found" + ); + + // Check that the hash of the provided message matches the one that was originally submitted. + bytes memory messageBytes = abi.encode(message); + require( + keccak256(messageBytes) == existingMessageInfo.messageHash, + "TeleporterMessenger: invalid message hash" + ); + + // Emit and make state variable changes before external calls when possible, + // though this function is protected by sender reentrancy guard. + emit SendCrossChainMessage( + messageID, message.destinationBlockchainID, message, existingMessageInfo.feeInfo + ); + + // Resubmit the message to the warp precompile now that we know + // the exact message was already submitted in the past. + WARP_MESSENGER.sendWarpMessage(messageBytes); + } + + /** + * @dev Both `senderNonReentrant` and `receiverNonReentrant` are used here to prevent the + * external call of `safeTransferFrom` from being reentrant, calling `receiveCrossChainMessage` + * to attribute rewards for this message, and then still adding fee amount for this message. + * Emits an {AddFeeAmount} event. + * Requirements: + * + * - `additionalFeeAmount` must be non-zero. + * - `message` must exist and not have been acknowledged with a receipt yet. + * - `feeTokenAddress` must match the fee asset contract address used in the original call to `sendCrossChainMessage`. + * @inheritdoc ITeleporterMessenger + */ + function addFeeAmount( + bytes32 messageID, + address feeTokenAddress, + uint256 additionalFeeAmount + ) external senderNonReentrant receiverNonReentrant { + // The additional fee amount must be non-zero. + require(additionalFeeAmount > 0, "TeleporterMessenger: zero additional fee amount"); + + // Do not allow adding a fee asset with contract address zero. + require( + feeTokenAddress != address(0), "TeleporterMessenger: zero fee asset contract address" + ); + + // If a receipt has been received for this message, its hash and fee information + // will be cleared from state. At this point, you can not add to its fee. This is also the + // case if the given message never existed. + require( + sentMessageInfo[messageID].messageHash != bytes32(0), + "TeleporterMessenger: message not found" + ); + + // Check that the fee contract address matches the one that was originally used. Only a single + // fee asset can be used to incentivize the delivery of a given message. + // We require users to explicitly pass the same fee asset contract address here rather than just using + // the previously submitted asset type as a defensive measure to avoid having users accidentally confuse + // which asset they are paying. + require( + sentMessageInfo[messageID].feeInfo.feeTokenAddress == feeTokenAddress, + "TeleporterMessenger: invalid fee asset contract address" + ); + + // Transfer the additional fee amount to this Teleporter instance. + uint256 adjustedAmount = + SafeERC20TransferFrom.safeTransferFrom(IERC20(feeTokenAddress), additionalFeeAmount); + + // Store the updated fee amount, and emit it as an event. + sentMessageInfo[messageID].feeInfo.amount += adjustedAmount; + + emit AddFeeAmount(messageID, sentMessageInfo[messageID].feeInfo); + } + + /** + * @dev Emits a {ReceiveCrossChainMessage} event. + * Re-entrancy is explicitly disallowed between receiving functions. One message is not able to receive another message. + * Requirements: + * + * - `relayerRewardAddress` must not be the zero address. + * - `messageIndex` must specify a valid warp message in the transaction's storage slots. + * - Valid warp message provided in storage slots, and sender address matches the address of this contract. + * - Teleporter message `destinationBlockchainID` must match the `blockchainID` of this contract. + * - Teleporter message was not previously received. + * - Transaction was sent by an allowed relayer for corresponding teleporter message. + * + * @inheritdoc ITeleporterMessenger + */ + function receiveCrossChainMessage( + uint32 messageIndex, + address relayerRewardAddress + ) external receiverNonReentrant { + // Verify and parse the cross chain message included in the transaction access list + // using the warp message precompile. + (WarpMessage memory warpMessage, bool success) = + WARP_MESSENGER.getVerifiedWarpMessage(messageIndex); + require(success, "TeleporterMessenger: invalid warp message"); + + // Only allow for messages to be received from the same address as this teleporter contract. + // The contract should be deployed using the universal deployer pattern, such that it knows messages + // received from the same address on other chains were constructed using the same bytecode of this contract. + // This allows for trusting the message format and uniqueness as specified by sendCrossChainMessage. + require( + warpMessage.originSenderAddress == address(this), + "TeleporterMessenger: invalid origin sender address" + ); + + // Parse the payload of the message. + TeleporterMessage memory teleporterMessage = + abi.decode(warpMessage.payload, (TeleporterMessage)); + + // If the blockchain ID has yet to be initialized, do so now. + bytes32 blockchainID_ = initializeBlockchainID(); + + // Require that the message was intended for this blockchain. + require( + teleporterMessage.destinationBlockchainID == blockchainID_, + "TeleporterMessenger: invalid destination chain ID" + ); + + // Calculate the message ID of the message given the source blockchain ID and message nonce. + bytes32 messageID = calculateMessageID( + warpMessage.sourceChainID, blockchainID_, teleporterMessage.messageNonce + ); + + // Require that the message has not been received previously. + require(!_messageReceived(messageID), "TeleporterMessenger: message already received"); + + // Check that the caller is allowed to deliver this message. + require( + _checkIsAllowedRelayer(msg.sender, teleporterMessage.allowedRelayerAddresses), + "TeleporterMessenger: unauthorized relayer" + ); + + // Mark the message as received. + _markMessageReceived(messageID, teleporterMessage.messageNonce); + + // Store the relayer reward address if non-zero. + if (relayerRewardAddress != address(0)) { + _relayerRewardAddresses[messageID] = relayerRewardAddress; + } + + // Process the receipts that were included in the teleporter message by paying the + // fee for the messages are reward to the given relayers. + uint256 length = teleporterMessage.receipts.length; + for (uint256 i; i < length; ++i) { + _markReceipt(blockchainID_, warpMessage.sourceChainID, teleporterMessage.receipts[i]); + } + + // Store the receipt of this message delivery. + receiptQueues[warpMessage.sourceChainID].enqueue( + TeleporterMessageReceipt({ + receivedMessageNonce: teleporterMessage.messageNonce, + relayerRewardAddress: relayerRewardAddress + }) + ); + + emit ReceiveCrossChainMessage( + messageID, + warpMessage.sourceChainID, + msg.sender, + relayerRewardAddress, + teleporterMessage + ); + + // Execute the message. + if (teleporterMessage.message.length > 0) { + _handleInitialMessageExecution(messageID, warpMessage.sourceChainID, teleporterMessage); + } + } + + /** + * @dev A Teleporter message has an associated `requiredGasLimit` that is used to execute the message. + * If the `requiredGasLimit` is too low, then the message execution will fail. This method allows + * for retrying the execution of a message with a higher gas limit. Contrary to `receiveCrossChainMessage`, + * which will only use `requiredGasLimit` in the sub-call to execute the message, this method may + * use all of the gas available in the transaction. + * + * Reverts if the message execution fails again on the specified message. + * Emits a {MessageExecuted} event if the retry is successful. + * Requirements: + * + * - `message` must have previously failed to execute, and matches the hash of the failed message. + * + * @inheritdoc ITeleporterMessenger + */ + function retryMessageExecution( + bytes32 sourceBlockchainID, + TeleporterMessage calldata message + ) external receiverNonReentrant { + // Calculate the message ID based on the source blockchainID and message nonce. + // If the blockchain ID has yet to be initialized, no messages have ever been received by + // this contract, meaning that the message to be retried will not be found in any event. + // Thus, don't need to initialize the blockchain ID here. + bytes32 messageID = + calculateMessageID(sourceBlockchainID, blockchainID, message.messageNonce); + + // Check that the hash of the payload provided matches the hash of the payload that previously failed to execute. + bytes32 failedMessageHash = receivedFailedMessageHashes[messageID]; + require(failedMessageHash != bytes32(0), "TeleporterMessenger: message not found"); + require( + keccak256(abi.encode(message)) == failedMessageHash, + "TeleporterMessenger: invalid message hash" + ); + + // Check that the target address has fully initialized contract code prior to calling it. + // If the target address does not have code, the execution automatically fails. + require( + message.destinationAddress.code.length > 0, + "TeleporterMessenger: destination address has no code" + ); + + // Clear the failed message hash from state prior to retrying its execution to redundantly prevent + // reentrance attacks (on top of the nonReentrant guard). + emit MessageExecuted(messageID, sourceBlockchainID); + delete receivedFailedMessageHashes[messageID]; + + // Re-encode the payload by ABI encoding a call to the {receiveTeleporterMessage} function + // defined by the {ITeleporterReceiver} interface. + // If the destination address does not implement {receiveTeleporterMessage}, but does implement + // a fallback function, then the fallback function will be called instead. + bytes memory payload = abi.encodeCall( + ITeleporterReceiver.receiveTeleporterMessage, + (sourceBlockchainID, message.originSenderAddress, message.message) + ); + + // Reattempt the message execution with all of the gas left available for execution of this transaction. + // Use all of the gas left because this message has already been successfully received, and it is the + // caller's responsibility to provide as much gas as is needed. Compared to the initial delivery, where + // the relayer should still receive their reward even if the message execution takes more gas than expected. + // Require that the call be successful such that in the failure case this transaction reverts and the + // message can be retried again if desired. + bool success = _tryExecuteMessage(message.destinationAddress, gasleft(), payload); + require(success, "TeleporterMessenger: retry execution failed"); + } + + /** + * @dev There is no explicit limit to the number of receipts able to be sent by a {sendSpecifiedReceipts} message because + * this method is intended to be used by relayers themselves to ensure their receipts get returned. + * There is no fee associated with the empty message, and the same relayer is expected to relay it + * themselves in order to claim their rewards, so it is their responsibility to ensure that the necessary + * gas is provided for however many receipts are being retried. + * + * These specified receipts are not removed from their corresponding receipt queue because there + * is no efficient way to remove a specific receipt from an arbitrary position in the queue, and it is + * harmless for receipts to be sent multiple times within the protocol. + * + * Emits {SendCrossChainMessage} event. + * Requirements: + * - `messageIDs` must all be valid and have existing receipts. + * + * @inheritdoc ITeleporterMessenger + */ + function sendSpecifiedReceipts( + bytes32 sourceBlockchainID, + bytes32[] calldata messageIDs, + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external senderNonReentrant returns (bytes32) { + // If the blockchain ID has yet to be initialized, no messages have ever been received by + // this contract, meaning that the receipt(s) will not be found in any event. + // Thus, don't need to initialize the blockchain ID here. + bytes32 blockchainID_ = blockchainID; + + // Iterate through the specified message IDs and create teleporter receipts to send back. + TeleporterMessageReceipt[] memory receiptsToSend = + new TeleporterMessageReceipt[](messageIDs.length); + uint256 length = messageIDs.length; + for (uint256 i; i < length; ++i) { + bytes32 receivedMessageID = messageIDs[i]; + + // Get the nonce for this message ID. + uint256 receivedMessageNonce = _receivedMessageNonces[receivedMessageID]; + require(receivedMessageNonce != 0, "TeleporterMessenger: receipt not found"); + + // Check that the message ID was received from the specified source blockchain. + require( + receivedMessageID + == calculateMessageID(sourceBlockchainID, blockchainID_, receivedMessageNonce), + "TeleporterMessenger: message ID not from source blockchain" + ); + + // Get the relayer reward address for the message. + address relayerRewardAddress = _relayerRewardAddresses[receivedMessageID]; + + receiptsToSend[i] = TeleporterMessageReceipt({ + receivedMessageNonce: receivedMessageNonce, + relayerRewardAddress: relayerRewardAddress + }); + } + + return _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: sourceBlockchainID, + destinationAddress: address(0), + feeInfo: feeInfo, + requiredGasLimit: uint256(0), + allowedRelayerAddresses: allowedRelayerAddresses, + message: new bytes(0) + }), + receiptsToSend + ); + } + + /** + * @dev Requirements: + * + * - `rewardAmount` must be non-zero. + * + * @inheritdoc ITeleporterMessenger + */ + function redeemRelayerRewards( + address feeAsset + ) external { + uint256 rewardAmount = _relayerRewardAmounts[msg.sender][feeAsset]; + require(rewardAmount > 0, "TeleporterMessenger: no reward to redeem"); + + // Zero the reward balance before calling the external ERC20 to transfer the + // reward to prevent any possible re-entrancy. + delete _relayerRewardAmounts[msg.sender][feeAsset]; + + emit RelayerRewardsRedeemed(msg.sender, feeAsset, rewardAmount); + + // "Fee on transfer" tokens do not require a special case here because + // the amount credited to the caller does not affect this contract's accounting. + // The reward is considered paid in full in all cases. + IERC20(feeAsset).safeTransfer(msg.sender, rewardAmount); + } + + /** + * @inheritdoc ITeleporterMessenger + */ + function getMessageHash( + bytes32 messageID + ) external view returns (bytes32) { + return sentMessageInfo[messageID].messageHash; + } + + /** + * @inheritdoc ITeleporterMessenger + */ + function messageReceived( + bytes32 messageID + ) external view returns (bool) { + return _messageReceived(messageID); + } + + /** + * @inheritdoc ITeleporterMessenger + */ + function getRelayerRewardAddress( + bytes32 messageID + ) external view returns (address) { + require(_messageReceived(messageID), "TeleporterMessenger: message not received"); + return _relayerRewardAddresses[messageID]; + } + + /** + * @inheritdoc ITeleporterMessenger + */ + function checkRelayerRewardAmount( + address relayer, + address feeAsset + ) external view returns (uint256) { + return _relayerRewardAmounts[relayer][feeAsset]; + } + + /** + * @inheritdoc ITeleporterMessenger + */ + function getFeeInfo( + bytes32 messageID + ) external view returns (address, uint256) { + TeleporterFeeInfo memory feeInfo = sentMessageInfo[messageID].feeInfo; + return (feeInfo.feeTokenAddress, feeInfo.amount); + } + + /** + * @notice Gets the next message ID to be used for a message sent from the contract instance. + * @return The next message ID to be used for a message sent from the contract instance. + */ + function getNextMessageID( + bytes32 destinationBlockchainID + ) external view returns (bytes32) { + bytes32 blockchainID_ = blockchainID; + require(blockchainID_ != bytes32(0), "TeleporterMessenger: zero blockchain ID"); + uint256 nextMessageNonce = messageNonce + 1; + return calculateMessageID(blockchainID_, destinationBlockchainID, nextMessageNonce); + } + + /** + * @inheritdoc ITeleporterMessenger + */ + function getReceiptQueueSize( + bytes32 sourceBlockchainID + ) external view returns (uint256) { + return receiptQueues[sourceBlockchainID].size(); + } + + /** + * @inheritdoc ITeleporterMessenger + */ + function getReceiptAtIndex( + bytes32 sourceBlockchainID, + uint256 index + ) external view returns (TeleporterMessageReceipt memory) { + return receiptQueues[sourceBlockchainID].getReceiptAtIndex(index); + } + + /** + * @notice If not already set, initializes blockchainID by getting the current + * blockchain ID value from the Warp precompile. + * @dev Emits {BlockchainIDInitialized} event. + * @return The current blockchain ID. + */ + function initializeBlockchainID() public returns (bytes32) { + bytes32 blockchainID_ = blockchainID; + if (blockchainID_ == bytes32(0)) { + blockchainID_ = WARP_MESSENGER.getBlockchainID(); + require(blockchainID_ != bytes32(0), "TeleporterMessenger: zero blockchain ID"); + blockchainID = blockchainID_; + emit BlockchainIDInitialized(blockchainID_); + } + return blockchainID_; + } + + /** + * @notice Calculates the message ID for a message sent from this contract instance with the + * given source blockchain ID, destination blockchain ID, and message nonce. + */ + function calculateMessageID( + bytes32 sourceBlockchainID, + bytes32 destinationBlockchainID, + uint256 nonce + ) public view returns (bytes32) { + return + keccak256(abi.encode(address(this), sourceBlockchainID, destinationBlockchainID, nonce)); + } + + /** + * @dev Checks whether `delivererAddress` is allowed to deliver the message. + */ + function _checkIsAllowedRelayer( + address delivererAddress, + address[] memory allowedRelayers + ) internal pure returns (bool) { + // An empty allowed relayers list means anyone is allowed to deliver the message. + if (allowedRelayers.length == 0) { + return true; + } + + // Otherwise, the deliverer address must be included in allowedRelayers. + uint256 length = allowedRelayers.length; + for (uint256 i; i < length; ++i) { + if (allowedRelayers[i] == delivererAddress) { + return true; + } + } + return false; + } + + /** + * @dev Helper function for sending a teleporter message cross chain. + * Constructs the Teleporter message and sends it through the Warp Messenger precompile, + * and performs fee transfer if necessary. + * + * Emits a {SendCrossChainMessage} event. + */ + function _sendTeleporterMessage( + TeleporterMessageInput memory messageInput, + TeleporterMessageReceipt[] memory receipts + ) private returns (bytes32) { + // If the blockchain ID has yet to be initialized, do so now. + bytes32 blockchainID_ = initializeBlockchainID(); + + // Get the message ID to use for this message by incrementing it. + uint256 messageNonce_ = ++messageNonce; + bytes32 messageID = + calculateMessageID(blockchainID_, messageInput.destinationBlockchainID, messageNonce_); + + // Construct and serialize the message. + TeleporterMessage memory teleporterMessage = TeleporterMessage({ + messageNonce: messageNonce_, + originSenderAddress: msg.sender, + destinationBlockchainID: messageInput.destinationBlockchainID, + destinationAddress: messageInput.destinationAddress, + requiredGasLimit: messageInput.requiredGasLimit, + allowedRelayerAddresses: messageInput.allowedRelayerAddresses, + receipts: receipts, + message: messageInput.message + }); + bytes memory teleporterMessageBytes = abi.encode(teleporterMessage); + + // If the fee amount is non-zero, transfer the asset into control of this TeleporterMessenger contract instance. + // The fee is allowed to be 0 because it's possible for someone to run their own relayer and deliver their own messages, + // which does not require further incentivization. They still must pay the transaction fee to submit the message, so + // this is not a DOS vector in terms of being able to submit zero-fee messages. + uint256 adjustedFeeAmount; + if (messageInput.feeInfo.amount > 0) { + // If the fee amount is non-zero, check that the contract address is not address(0) + require( + messageInput.feeInfo.feeTokenAddress != address(0), + "TeleporterMessenger: zero fee asset contract address" + ); + + adjustedFeeAmount = SafeERC20TransferFrom.safeTransferFrom( + IERC20(messageInput.feeInfo.feeTokenAddress), messageInput.feeInfo.amount + ); + } + + // Store the fee asset and amount to be paid to the relayer of this message upon receiving the receipt. + // Also store the message hash so that it can be retried until a receipt of its delivery is received back. + TeleporterFeeInfo memory adjustedFeeInfo = TeleporterFeeInfo({ + feeTokenAddress: messageInput.feeInfo.feeTokenAddress, + amount: adjustedFeeAmount + }); + sentMessageInfo[messageID] = SentMessageInfo({ + messageHash: keccak256(teleporterMessageBytes), + feeInfo: adjustedFeeInfo + }); + + emit SendCrossChainMessage( + messageID, messageInput.destinationBlockchainID, teleporterMessage, adjustedFeeInfo + ); + + // Submit the message to the AWM precompile. + WARP_MESSENGER.sendWarpMessage(teleporterMessageBytes); + + return messageID; + } + + /** + * @dev Marks a message as being received by storing the message nonce associated with the + * given message ID. The message nonce must not be zero in order to be able to distinguish between + * received and unreceived messages based on their ID. + */ + function _markMessageReceived(bytes32 messageID, uint256 messageNonce_) private { + require(messageNonce_ != 0, "TeleporterMessenger: zero message nonce"); + _receivedMessageNonces[messageID] = messageNonce_; + } + + /** + * @dev Records the receival of a receipt for a message previously sent to the `destinationBlockchainID` with the given `messageID`. + * + * Returns early if a receipt was already previously received for this message, or if the message never existed. Otherwise, deletes + * the message information from `sentMessageInfo` and increments the reward redeemable by the specified relayer reward address. + * + * Emits a {ReceiptReceived} event if the receipt was successfully received. + */ + function _markReceipt( + bytes32 sourceBlockchainID_, + bytes32 destinationBlockchainID_, + TeleporterMessageReceipt memory receipt + ) private { + bytes32 messageID = calculateMessageID( + sourceBlockchainID_, destinationBlockchainID_, receipt.receivedMessageNonce + ); + + // Get the information about the sent message to be marked as received. + SentMessageInfo memory messageInfo = sentMessageInfo[messageID]; + + // If the message hash does not exist, it could be the case that the receipt was already + // received for this message (it's possible for receipts to be sent more than once) + // or that the other chain sent an invalid receipt. Return early since this is an expected + // case where there is no fee to be paid for the given message. + if (messageInfo.messageHash == bytes32(0)) { + return; + } + + // Delete the message information from state now that it is known to be received. + delete sentMessageInfo[messageID]; + + // Increment the fee/reward amount owed to the relayer for having delivered + // the message identified in this receipt. + _relayerRewardAmounts[receipt.relayerRewardAddress][messageInfo.feeInfo.feeTokenAddress] += + messageInfo.feeInfo.amount; + + emit ReceiptReceived( + messageID, destinationBlockchainID_, receipt.relayerRewardAddress, messageInfo.feeInfo + ); + } + + /** + * @dev Attempts to execute the newly received message. + * + * Only revert in the event that the message deliverer (relayer) did not provide enough gas to handle the execution + * (including possibly storing a failed message in state). All execution specific errors (i.e. invalid call data, etc) + * that are not in the relayer's control are caught and handled properly. + * + * Emits a {MessageExecuted} event if the call on destination address is successful. + * Emits a {MessageExecutionFailed} event if the call on destination address fails with formatted call data. + * Requirements: + * + * - There is enough gas left to cover `message.requiredGasLimit`. + */ + function _handleInitialMessageExecution( + bytes32 messageID, + bytes32 sourceBlockchainID, + TeleporterMessage memory message + ) private { + // Check that the message delivery was provided the required gas amount as specified by the sender. + // If the required gas amount is provided, the message will be considered received whether or not + // its execution succeeds, such that the relayer can claim their fee reward. However, if the message + // execution fails, the message hash will be stored in state such that anyone can try to provide more + // gas to successfully execute the message. + require(gasleft() >= message.requiredGasLimit, "TeleporterMessenger: insufficient gas"); + + // The destination address must have fully initialized contract code in order for the message + // to call it. If the destination address does not have code, store the message as a failed + // execution so that it can be retried in the future should a contract be later deployed to + // the address. + if (message.destinationAddress.code.length == 0) { + _storeFailedMessageExecution(messageID, sourceBlockchainID, message); + return; + } + + // Encode the payload by ABI encoding a call to the {receiveTeleporterMessage} function + // defined by the {ITeleporterReceiver} interface. + bytes memory payload = abi.encodeCall( + ITeleporterReceiver.receiveTeleporterMessage, + (sourceBlockchainID, message.originSenderAddress, message.message) + ); + + // Call the destination address of the message with the formatted call data. Only provide the required + // gas limit to the sub-call so that the end application cannot consume an arbitrary amount of gas. + bool success = + _tryExecuteMessage(message.destinationAddress, message.requiredGasLimit, payload); + + // If the execution failed, store a hash of the message in state such that its + // execution can be retried again in the future with a higher gas limit (paid by whoever + // retries). Either way, the message will now be considered received since the relayer + // provided enough gas to meet the required gas limit. + if (!success) { + _storeFailedMessageExecution(messageID, sourceBlockchainID, message); + return; + } + + emit MessageExecuted(messageID, sourceBlockchainID); + } + + function _tryExecuteMessage( + address target, + uint256 gasLimit, + bytes memory payload + ) private returns (bool) { + // Call the destination address of the message with the provided payload and amount of gas. + // + // Assembly is used for the low-level call to avoid unnecessary expansion of the return data in memory. + // This prevents possible "return bomb" vectors where the external contract could force the caller + // to use an arbitrary amount of gas. See Solidity issue here: https://github.com/ethereum/solidity/issues/12306 + bool success; + // solhint-disable-next-line no-inline-assembly + assembly { + success := + call( + gasLimit, // gas provided to the call + target, // call target + 0, // zero value + add(payload, 0x20), // input data - 0x20 needs to be added to an array because the first 32-byte slot contains the array length (0x20 in hex is 32 in decimal). + mload(payload), // input data size - mload returns mem[p..(p+32)], which is the first 32-byte slot of the array. In this case, the array length. + 0, // output + 0 // output size + ) + } + return success; + } + + /** + * @dev Stores the hash of a message that has been successfully received but fails to execute properly + * such that the message execution can be retried by anyone in the future. + */ + function _storeFailedMessageExecution( + bytes32 messageID, + bytes32 sourceBlockchainID, + TeleporterMessage memory message + ) private { + receivedFailedMessageHashes[messageID] = keccak256(abi.encode(message)); + + // Emit a failed execution event for anyone monitoring unsuccessful messages to retry. + emit MessageExecutionFailed(messageID, sourceBlockchainID, message); + } + + /** + * @dev Checks if a given message has been received. + * @return A boolean representing if the given message has been received or not. + */ + function _messageReceived( + bytes32 messageID + ) private view returns (bool) { + return _receivedMessageNonces[messageID] != 0; + } +} diff --git a/icm-contracts/contracts/teleporter/registry/README.md b/icm-contracts/contracts/teleporter/registry/README.md new file mode 100644 index 000000000..502f2312d --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/README.md @@ -0,0 +1,210 @@ +# TeleporterMessenger Contracts Upgradability + +## Overview + +The `TeleporterMessenger` contract is non-upgradable, once a version of the contract is deployed it cannot be changed. This is with the intention of preventing any changes to the deployed contract that could potentially introduce bugs or vulnerabilities. + +However, there could still be new versions of `TeleporterMessenger` contracts needed to be deployed in the future. `TeleporterRegistry` provides applications that use a `TeleporterMessenger` instance a minimal step process to integrate with new versions of `TeleporterMessenger`. + +The `TeleporterRegistry` maintains a mapping of `TeleporterMessenger` contract versions to their addresses. When a new `TeleporterMessenger` version is deployed, its address can be added to the `TeleporterRegistry`. The `TeleporterRegistry` can only be updated through an ICM off-chain message that meets the following requirements: + +- `sourceChainAddress` must match `VALIDATORS_SOURCE_ADDRESS = address(0)` + - The zero address can only be set as the source chain address by an ICM off-chain message, and cannot be set by an on-chain ICM message. +- `sourceBlockchainID` must match the blockchain ID that the registry is deployed on +- `destinationBlockchainID` must match the blockchain ID that the registry is deployed on +- `destinationAddress` must match the address of the registry + +In the `TeleporterRegistry` contract, the `latestVersion` state variable returns the highest version number that has been registered in the registry. The `getLatestTeleporter` function returns the `ITeleporterMessenger` that is registered with the corresponding version. + +## Design + +- `TeleporterRegistry` is deployed on each blockchain that needs to keep track of `TeleporterMessenger` contract versions. +- The registry's contract address on each blockchain does not need to be the same, and does not require a Nick's method transaction for deployment. +- Each registry's mapping of version to contract address is independent of registries on other blockchains, and chains can decide on their own registry mapping entries. +- Each blockchain should only have one canonical `TeleporterRegistry` contract. +- `TeleporterRegistry` contract can be initialized through a list of initial registry entries, which are `TeleporterMessenger` contract versions and their addresses. +- The registry keeps track of a mapping of `TeleporterMessenger` contract versions to their addresses, and vice versa, a mapping of `TeleporterMessenger` contract addresses to their versions. +- Version zero is an invalid version, and is used to indicate that a `TeleporterMessenger` contract has not been registered yet. +- Once a version number is registered in the registry, it cannot be changed, but a previous registered protocol address can be added to the registry with a new version. This is especially important in the case of a rollback to a previous `TeleporterMessenger` version, in which case the previous `TeleporterMessenger` contract address would need to be registered with a new version to the registry. + +## Integrating `TeleporterRegistryApp` into a dApp + +
+ Upgrade UML diagram +
+ +[TeleporterRegistryApp](./TeleporterRegistryApp.sol) is an abstract contract that helps integrate the `TeleporterRegistry` into ICM contracts. To support upgradeable contracts, there is also a corresponding `TeleporterRegistryAppUpgradeable` contract that is upgrade compatible. By inheriting from `TeleporterRegistryApp`, dApps get: + +- Ability to send ICM messages through the latest version of the `TeleporterMessenger` contract registered in the Teleporter registry. (The dApp can also override this to use a specific version of the `TeleporterMessenger` contract.) +- `minTeleporterVersion` management that allows the dApp to specify the minimum `TeleporterMessenger` version that can send messages to the dApp. +- Access controlled utility to update the `minTeleporterVersion` +- Access controlled utility to pause/unpause interaction with specific `TeleporterMessenger` addresses. + +To integrate `TeleporterRegistryApp` with a dApp, pass in the Teleporter registry address inside the constructor. For upgradeable contracts `TeleporterRegistryAppUpgradeable` can be inherited, and the derived contract's `initializer` function should call either `__TeleporterRegistryApp_init` or `__TeleporterRegistryApp_init_unchained` An example dApp looks like: + +```solidity +// An example dApp that integrates with the Teleporter registry +// to send/receive ICM messages. +contract ExampleApp is + TeleporterRegistryApp +{ + ... + // Constructor passes in the Teleporter registry address + // to the TeleporterRegistryApp contract. + constructor( + address teleporterRegistryAddress, + uint256 minTeleporterVersion + ) TeleporterRegistryApp(teleporterRegistryAddress, minTeleporterVersion) { + currentBlockchainID = IWarpMessenger(WARP_PRECOMPILE_ADDRESS) + .getBlockchainID(); + } + ... + // Handles receiving ICM messages, + // and also checks that the sender is a valid TeleporterMessenger contract. + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message + ) internal override { + // implementation + } + + // Implements the access control checks for the dApp's interaction with TeleporterMessenger versions. + function _checkTeleporterRegistryAppAccess() internal view virtual override { + //implementation + } + +} +``` + +### Checking TeleporterRegistryApp access + +To prevent anyone from calling the dApp's `updateMinTeleporterVersion`, which would disallow messages from old `TeleporterMessenger` versions from being received, this function should be safeguarded with access controls. All contracts deriving from `TeleporterRegistryApp` will need to implement `TeleporterRegistryApp._checkTeleporterRegistryAppAccess`. For example, [TeleporterRegistryOwnableApp](./TeleporterRegistryOwnableApp.sol) is an abstract contract that inherits `TeleporterRegistryApp`, and implements `_checkTeleporterRegistryAppAccess` to check whether the caller is the owner. There is also a corresponding `TeleporterRegistryOwnableAppUpgradeable` contract that is upgrade compatible. + +```solidity + function _checkTeleporterRegistryAppAccess() internal view virtual override { + _checkOwner(); + } +``` + +Another example would be a dApp that has different roles and priveleges. `_checkTeleporterRegistryAppAccess` can be implemented to check whether the caller is a specific role. + +```solidity + function _checkTeleporterRegistryAppAccess() internal view virtual override { + require( + hasRole(TELEPORTER_REGISTRY_APP_ADMIN, _msgSender()), + "TeleporterRegistryApp: caller does not have access" + ); + } +``` + +### Sending with specific TeleporterMessenger version + +For sending messages with the Teleporter registry, dApps should use `TeleporterRegistryApp._getTeleporterMessenger`. This function by default extends `TeleporterRegistry.getLatestTeleporter`, using the latest version, and adds an extra check on whether the latest `TeleporterMessenger` address is paused. If the dApp wants to send a message through a specific `TeleporterMessenger` version, it can override `_getTeleporterMessenger()` to use the specific `TeleporterMessenger` version with `TeleporterRegistry.getTeleporterFromVersion`. + +The `TeleporterRegistryApp._sendTeleporterMessage` function makes sending ICM messages easier. The function uses `_getTeleporterMessenger` to get the sending `TeleporterMessenger` version, pays for `TeleporterMessenger` fees from the dApp's balance, and sends the cross chain message. + +Using latest version: + +```solidity + ITeleporterMessenger teleporterMessenger = _getTeleporterMessenger(); +``` + +Using specific version: + +```solidity + // Override _getTeleporterMessenger to use specific version. + function _getTeleporterMessenger() internal view override returns (ITeleporterMessenger) { + ITeleporterMessenger teleporter = teleporterRegistry + .getTeleporterFromVersion($VERSION); + require( + !pausedTeleporterAddresses[address(teleporter)], + "TeleporterRegistryApp: Teleporter sending version paused" + ); + + return teleporter; + } + + ITeleporterMessenger teleporterMessenger = _getTeleporterMessenger(); +``` + +### Receiving from specific TeleporterMessenger versions + +`TeleporterRegistryApp` also provides an initial implementation of [ITeleporterReceiver.receiveTeleporterMessage](../ITeleporterReceiver.sol) that ensures `_msgSender` is a `TeleporterMessenger` contract with a version greater than or equal to `minTeleporterVersion`. This supports the case where a dApp wants to use a new version of the `TeleporterMessenger` contract, but still wants to be able to receive messages from the old `TeleporterMessenger` contract.The dApp can override `_receiveTeleporterMessage` to implement its own logic for receiving messages from `TeleporterMessenger` contracts. + +## Managing a TeleporterRegistryApp dApp + +dApps that implement `TeleporterRegistryApp` automatically use the latest `TeleporterMessenger` version registered with the `TeleporterRegistry`. Interaction with underlying `TeleporterMessenger` versions can be managed by setting the minimum `TeleporterMessenger` version, and pausing and unpausing specific versions. + +The following sections include example `cast send` commands for issuing transactions that call contract functions. See the [Foundry Book](https://book.getfoundry.sh/reference/cast/cast-send) for details on how to issue transactions using common wallet options. + +### Managing the Minimum TeleporterMessenger version + +The `TeleporterRegistryApp` contract constructor saves the Teleporter registry in a state variable used by the inheriting dApp contract, and initializes a `minTeleporterVersion` to the highest `TeleporterMessenger` version registered in `TeleporterRegistry`. `minTeleporterVersion` is used to allow dApp's to specify the `TeleporterMessenger` versions allowed to interact with it. + +#### Updating `minTeleporterVersion` + +The `TeleporterRegistryApp.updateMinTeleporterVersion` function updates the `minTeleporterVersion` used to check which `TeleporterMessenger` versions can be used for sending and receiving messages. **Once the `minTeleporterVersion` is increased, any undelivered messages sent by other chains using older versions of `TeleporterMessenger` will never be able to be received**. The `updateMinTeleporterVersion` function can only be called with a version greater than the current `minTeleporterVersion` and less than `latestVersion` in the Teleporter registry. + +> Example: Update the minimum TeleporterMessenger version to 2 +> +> ```bash +> cast send "updateMinTeleporterVersion(uint256)" 2 +> ``` + +### Pausing TeleporterMessenger version interactions + +dApps that inherit from `TeleporterRegistryApp` can pause `TeleporterMessenger` interactions by calling `TeleporterRegistryApp.pauseTeleporterAddress`. This function prevents the dApp contract from interacting with the paused `TeleporterMessenger` address when sending or receiving ICM messages. + +`pauseTeleporterAddress` can only be called by addresses that passes the dApp's `TeleporterRegistryApp._checkTeleporterRegistryAppAccess` check. + +The `TeleporterMessenger` address corresponding to a `TeleporterMessenger` version can be fetched from the registry with `TeleporterRegistry.getAddressFromVersion` + +> Example: Pause TeleporterMessenger version 3 +> +> ```bash +> versionThreeAddress=$(cast call "getAddressFromVersion(uint256)(address)" 3) +> cast send "pauseTeleporterAddress(address)" $versionThreeAddress +> ``` + +#### Pause all TeleporterMessenger interactions + +To pause all `TeleporterMessenger` interactions, `TeleporterRegistryApp.pauseTeleporterAddress` must be called for every `TeleporterMessenger` version from the `minTeleporterVersion` to the latest `TeleporterMessenger` version registered in `TeleporterRegistry`. Note that there may be gaps in `TeleporterMessenger` versions registered with `TeleporterRegistry`, but they will always be in increasing order. The latest `TeleporterMessenger` version can be obtained by inspecting the public variable `TeleporterRegistry.latestVersion`. The `minTeleporterVersion` can be obtained by calling `TeleporterRegistryApp.getMinTeleporterVersion`. + +> Example: Pause all registered TeleporterMessenger versions +> +> ```bash +> # Fetch the minimum TeleporterMessenger version +> minVersion=$(cast call "getMinTeleporterVersion()(uint256)") +> +> # Fetch the latest registered version +> latestVersion=$(cast call "latestVersion()(uint256)") +> +> # Pause all registered versions +> for ((version=minVersion; version<=latestVersion; version++)) +> do +> # Fetch the version address if it's registered +> versionAddress=$(cast call "getAddressFromVersion(uint256)(address)" $version) +> +> if [ $? -eq 0 ]; then +> # If cast call is successful, proceed to cast send +> cast send "pauseTeleporterAddress(address)" $versionAddress +> else +> # If cast call fails, print an error message and skip to the next iteration +> echo "Version $version not registered. Skipping." +> fi +> done +> ``` + +#### Unpausing TeleporterMessenger version interactions + +As with pausing, dApps can unpause `TeleporterMessenger` interactions by calling `TeleporterRegistryApp.unpauseTeleporterAddress`. This unpause function allows receiving `TeleporterMessenger` message from the unpaused `TeleporterMessenger` address, and also enables the sending of messages through the unpaused `TeleporterMessenger` address in `_getTeleporterMessenger()`. Unpausing is also only allowed by addresses passing the dApp's `_checkTeleporterRegistryAppAccess` check. + +Note that receiving `TeleporterMessenger` messages is still governed by the `minTeleporterVersion` check, so even if a `TeleporterMessenger` address is unpaused, the dApp will not receive messages from the unpaused `TeleporterMessenger` address if the `TeleporterMessenger` version is less than `minTeleporterVersion`. + +> Example: Unpause TeleporterMessenger version 3 +> +> ```bash +> versionThreeAddress=$(cast call "getAddressFromVersion(uint256)(address)" 3) +> cast send "unpauseTeleporterAddress(address)" $versionThreeAddress +> ``` diff --git a/icm-contracts/contracts/teleporter/registry/TeleporterRegistry.sol b/icm-contracts/contracts/teleporter/registry/TeleporterRegistry.sol new file mode 100644 index 000000000..3cf95a5e0 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/TeleporterRegistry.sol @@ -0,0 +1,221 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ITeleporterMessenger} from "@teleporter/ITeleporterMessenger.sol"; +import {IWarpMessenger, WarpMessage} from "@subnet-evm/IWarpMessenger.sol"; + +// Registry entry that represents a mapping between protocolAddress and Teleporter version. +struct ProtocolRegistryEntry { + uint256 version; + address protocolAddress; +} + +/** + * @dev TeleporterRegistry contract provides an upgrade mechanism for {ITeleporterMessenger} contracts + * through Warp off-chain messages + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract TeleporterRegistry { + /** + * @notice Address that the off-chain Warp message sets as the "source" address. + * @dev The address is not owned by any EOA or smart contract account, so it + * cannot possibly be the source address of any other Warp message emitted by the VM. + */ + address public constant VALIDATORS_SOURCE_ADDRESS = address(0); + + /** + * @notice Warp precompile used for sending and receiving Warp messages. + */ + IWarpMessenger public constant WARP_MESSENGER = + IWarpMessenger(0x0200000000000000000000000000000000000005); + + /** + * @notice The maximum version increment allowed when adding a new protocol version. + */ + uint256 public constant MAX_VERSION_INCREMENT = 500; + + /** + * @notice The blockchain ID of the chain the contract is deployed on. + */ + bytes32 public immutable blockchainID; + + /** + * @notice The latest protocol version. + * @dev 0 means no protocol version has been added, and isn't a valid version. + */ + uint256 public latestVersion; + + /** + * @notice Mappings that keep track of the protocol version and corresponding contract address. + */ + mapping(uint256 version => address protocolAddress) private _versionToAddress; + mapping(address protocolAddress => uint256 version) private _addressToVersion; + + /** + * @notice Emitted when a new protocol version is added to the registry. + */ + event AddProtocolVersion(uint256 indexed version, address indexed protocolAddress); + + /** + * @notice Emitted when the latest version is updated. + */ + event LatestVersionUpdated(uint256 indexed oldVersion, uint256 indexed newVersion); + + /** + * @dev Initializes the contract by setting `blockchainID` and `latestVersion`. + * Also adds the initial protocol versions to the registry. + */ + constructor( + ProtocolRegistryEntry[] memory initialEntries + ) { + blockchainID = WARP_MESSENGER.getBlockchainID(); + + uint256 length = initialEntries.length; + for (uint256 i; i < length; ++i) { + _addToRegistry(initialEntries[i]); + } + } + + /** + * @dev Receives a Warp off-chain message containing a new protocol version and address to be registered, + * and adds the new values to the respective mappings. + * If a version is greater than the current latest version, it will be set as the latest version. + * If a version is less than the current latest version, it is added to the registry, but + * doesn't change the latest version. + * + * Emits a {AddProtocolVersion} event when successful. + * Emits a {LatestVersionUpdated} event when a new protocol version greater than the current latest version is added. + * Requirements: + * + * - a valid Warp off-chain message must be provided. + * - source chain ID must be the same as the blockchain ID of the registry. + * - origin sender address must be the same as the `VALIDATORS_SOURCE_ADDRESS`. + * - destination address must be the same as the address of this registry. + */ + function addProtocolVersion( + uint32 messageIndex + ) external { + // Get the verified Warp message, and check that it was sent to this registry via a Warp off-chain message. + (WarpMessage memory message, bool success) = + WARP_MESSENGER.getVerifiedWarpMessage(messageIndex); + require(success, "TeleporterRegistry: invalid warp message"); + require( + message.sourceChainID == blockchainID, "TeleporterRegistry: invalid source chain ID" + ); + // Check that the message is sent through a Warp off-chain message. + require( + message.originSenderAddress == VALIDATORS_SOURCE_ADDRESS, + "TeleporterRegistry: invalid origin sender address" + ); + + (ProtocolRegistryEntry memory entry, address destinationAddress) = + abi.decode(message.payload, (ProtocolRegistryEntry, address)); + + // Check that the message is sent to the registry. + require( + destinationAddress == address(this), "TeleporterRegistry: invalid destination address" + ); + + _addToRegistry(entry); + } + + /** + * @dev Gets the latest {ITeleporterMessenger} contract. + */ + function getLatestTeleporter() external view returns (ITeleporterMessenger) { + return ITeleporterMessenger(getAddressFromVersion(latestVersion)); + } + + /** + * @dev Gets the {ITeleporterMessenger} contract of the given `version`. + * Requirements: + * + * - `version` must be a valid registered version. + */ + function getTeleporterFromVersion( + uint256 version + ) external view returns (ITeleporterMessenger) { + return ITeleporterMessenger(getAddressFromVersion(version)); + } + + /** + * @dev Gets the address of a protocol version. + * Requirements: + * + * - `version` must be a valid registered version. + */ + function getAddressFromVersion( + uint256 version + ) public view returns (address) { + require(version != 0, "TeleporterRegistry: zero version"); + address protocolAddress = _versionToAddress[version]; + require(protocolAddress != address(0), "TeleporterRegistry: version not found"); + return protocolAddress; + } + + /** + * @dev Gets the version of the given `protocolAddress`. + * Requirements: + * + * - `protocolAddress` must be a valid registered protocol address. + */ + function getVersionFromAddress( + address protocolAddress + ) public view returns (uint256) { + require(protocolAddress != address(0), "TeleporterRegistry: zero protocol address"); + uint256 version = _addressToVersion[protocolAddress]; + require(version != 0, "TeleporterRegistry: protocol address not found"); + return version; + } + + /** + * @dev Adds the new protocol version address to the registry. + * Updates latest version if the version is greater than the current latest version. + * + * Emits a {AddProtocolVersion} event when successful. + * Emits a {LatestVersionUpdated} event when a new protocol version greater than the current latest version is added. + * Note: `entry.protocolAddress` doesn't have to be a contract address, allowing a new protocol address to be registered before the contract is deployed. + * Requirements: + * + * - `entry.version` is not zero + * - `entry.version` is not already registered + * - `entry.protocolAddress` is not zero address + */ + function _addToRegistry( + ProtocolRegistryEntry memory entry + ) private { + require(entry.version != 0, "TeleporterRegistry: zero version"); + // Check that the version has not previously been registered. + require( + _versionToAddress[entry.version] == address(0), + "TeleporterRegistry: version already exists" + ); + require(entry.protocolAddress != address(0), "TeleporterRegistry: zero protocol address"); + + uint256 latestVersion_ = latestVersion; + require( + entry.version <= latestVersion_ + MAX_VERSION_INCREMENT, + "TeleporterRegistry: version increment too high" + ); + + _versionToAddress[entry.version] = entry.protocolAddress; + + // Since a protocol address can be registered multiple times, + // only update the version if the new version is greater than the current version. + if (entry.version > _addressToVersion[entry.protocolAddress]) { + _addressToVersion[entry.protocolAddress] = entry.version; + } + emit AddProtocolVersion(entry.version, entry.protocolAddress); + + // Set latest version if the version is greater than the current latest version. + if (entry.version > latestVersion_) { + latestVersion = entry.version; + emit LatestVersionUpdated(latestVersion_, entry.version); + } + } +} diff --git a/icm-contracts/contracts/teleporter/registry/TeleporterRegistryApp.sol b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryApp.sol new file mode 100644 index 000000000..d0e3c2867 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryApp.sol @@ -0,0 +1,279 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterRegistry} from "./TeleporterRegistry.sol"; +import {ITeleporterReceiver} from "@teleporter/ITeleporterReceiver.sol"; +import {ITeleporterMessenger, TeleporterMessageInput} from "@teleporter/ITeleporterMessenger.sol"; +import {Context} from "@openzeppelin/contracts@5.0.2/utils/Context.sol"; +import {ReentrancyGuard} from "@openzeppelin/contracts@5.0.2/utils/ReentrancyGuard.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; + +/** + * @dev TeleporterRegistryApp provides upgrade utility for applications built on top + * of the Teleporter protocol by integrating with the {TeleporterRegistry}. + * + * This contract is intended to be inherited by other contracts that wish to use the + * upgrade mechanism. It provides an interface that restricts access to only Teleporter + * versions that are greater than or equal to `minTeleporterVersion`. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract TeleporterRegistryApp is Context, ITeleporterReceiver, ReentrancyGuard { + using SafeERC20 for IERC20; + + // The Teleporter registry contract manages different Teleporter contract versions. + TeleporterRegistry public immutable teleporterRegistry; + /** + * @dev A mapping that keeps track of paused Teleporter addresses. + */ + mapping(address teleporterAddress => bool paused) private _pausedTeleporterAddresses; + + /** + * @dev The minimum required Teleporter version that the contract is allowed + * to receive messages from. Should only be updated by `_setMinTeleporterVersion` + */ + uint256 private _minTeleporterVersion; + + /** + * @dev Emitted when `minTeleporterVersion` is updated. + */ + event MinTeleporterVersionUpdated( + uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion + ); + + /** + * @dev Emitted when a Teleporter address is paused. + */ + event TeleporterAddressPaused(address indexed teleporterAddress); + + /** + * @dev Emitted when a Teleporter address is unpaused. + */ + event TeleporterAddressUnpaused(address indexed teleporterAddress); + + /** + * @dev Initializes the {TeleporterRegistryApp} contract by getting `teleporterRegistry` + * instance and setting `_minTeleporterVersion`. + * @param teleporterRegistryAddress The address of the Teleporter registry contract. + * The Teleporter registry contract should be deployed, and have at least one Teleporter version. + * @param minTeleporterVersion The minimum Teleporter version allowed for delivering messages. + * The minimum version should be less than or equal to the latest Teleporter version, and greater than 0. + */ + constructor(address teleporterRegistryAddress, uint256 minTeleporterVersion) { + require( + teleporterRegistryAddress != address(0), + "TeleporterRegistryApp: zero Teleporter registry address" + ); + + teleporterRegistry = TeleporterRegistry(teleporterRegistryAddress); + require( + teleporterRegistry.latestVersion() > 0, + "TeleporterRegistryApp: invalid Teleporter registry" + ); + _setMinTeleporterVersion(minTeleporterVersion); + } + + /** + * @dev See {ITeleporterReceiver-receiveTeleporterMessage} + * `nonReentrant` is a reentrancy guard that protects against multiple versions of the + * TeleporterMessengerContract delivering a message in the same call. Any internal calls + * will not be able to call functions also marked with `nonReentrant`. + * + * Requirements: + * + * - `_msgSender()` must be a Teleporter version greater than or equal to `minTeleporterVersion`. + */ + function receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes calldata message + ) external nonReentrant { + // Checks that `_msgSender()` matches a Teleporter version greater than or equal to `minTeleporterVersion`. + require( + teleporterRegistry.getVersionFromAddress(_msgSender()) >= _minTeleporterVersion, + "TeleporterRegistryApp: invalid Teleporter sender" + ); + + // Check against the paused Teleporter addresses. + require( + !isTeleporterAddressPaused(_msgSender()), + "TeleporterRegistryApp: Teleporter address paused" + ); + + _receiveTeleporterMessage(sourceBlockchainID, originSenderAddress, message); + } + + /** + * @dev Updates the minimum Teleporter version allowed for delivering Teleporer messages + * to this contract. + * + * To prevent anyone from being able to call this function, which would disallow messages + * from old Teleporter versions from being received, this function should be safeguarded with access + * controls. This is done by overriding the implementation of {_checkTeleporterRegistryAppAccess}. + */ + function updateMinTeleporterVersion( + uint256 version + ) public virtual { + _checkTeleporterRegistryAppAccess(); + _setMinTeleporterVersion(version); + } + + /** + * @dev Pauses a Teleporter address from interacting with this contract. + * After pausing a Teleporter address, it will no longer be able to deliver messages + * to this contract, and this contract will not send messages through that Teleporter address. + * The address does not need to be registered with the Teleporter registry. + * Emits a {TeleporterAddressPaused} event if successfully paused. + * Requirements: + * + * - `_msgSender()` must have Teleporter upgrade access. + * - `teleporterAddress` is not the zero address. + * - `teleporterAddress` is not already paused. + */ + function pauseTeleporterAddress( + address teleporterAddress + ) public virtual { + _checkTeleporterRegistryAppAccess(); + require(teleporterAddress != address(0), "TeleporterRegistryApp: zero Teleporter address"); + require( + !isTeleporterAddressPaused(teleporterAddress), + "TeleporterRegistryApp: address already paused" + ); + _pausedTeleporterAddresses[teleporterAddress] = true; + emit TeleporterAddressPaused(teleporterAddress); + } + + /** + * @dev Unpauses a Teleporter address from interacting with this contract. + * After unpausing a Teleporter address, it will again be able to deliver messages + * to this contract, and this contract can send messages through that Teleporter address. + * The address does not need to be registered with the Teleporter registry. + * Emits a {TeleporterAddressUnpaused} event if successfully unpaused. + * Requirements: + * + * - `_msgSender()` must have Teleporter upgrade access. + * - `teleporterAddress` is not the zero address. + * - `teleporterAddress` is already paused. + */ + function unpauseTeleporterAddress( + address teleporterAddress + ) public virtual { + _checkTeleporterRegistryAppAccess(); + require(teleporterAddress != address(0), "TeleporterRegistryApp: zero Teleporter address"); + require( + isTeleporterAddressPaused(teleporterAddress), + "TeleporterRegistryApp: address not paused" + ); + emit TeleporterAddressUnpaused(teleporterAddress); + _pausedTeleporterAddresses[teleporterAddress] = false; + } + + /** + * @dev Public getter for `_minTeleporterVersion`. + */ + function getMinTeleporterVersion() public view returns (uint256) { + return _minTeleporterVersion; + } + + /** + * @dev Checks if a Teleporter address is paused. + */ + function isTeleporterAddressPaused( + address teleporterAddress + ) public view virtual returns (bool) { + return _pausedTeleporterAddresses[teleporterAddress]; + } + + /** + * @dev Sets the minimum Teleporter version allowed for delivering Teleporter messages. + * Emits a {MinTeleporterVersionUpdated} event if the minimum Teleporter version was updated. + * Requirements: + * + * - `version` must be less than or equal to the latest Teleporter version. + * - `version` must be greater than the current minimum Teleporter version. + * + */ + function _setMinTeleporterVersion( + uint256 version + ) internal virtual { + uint256 latestTeleporterVersion = teleporterRegistry.latestVersion(); + uint256 oldMinTeleporterVersion = _minTeleporterVersion; + + require( + version <= latestTeleporterVersion, "TeleporterRegistryApp: invalid Teleporter version" + ); + require( + version > oldMinTeleporterVersion, + "TeleporterRegistryApp: not greater than current minimum version" + ); + + _minTeleporterVersion = version; + emit MinTeleporterVersionUpdated(oldMinTeleporterVersion, version); + } + + /** + * @dev Receives Teleporter messages and handles accordingly. + * This function should be overridden by contracts that inherit from this contract. + */ + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message + ) internal virtual; + + /** + * @dev Checks that the caller has access to update the minimum Teleporter version + * allowed for delivering Teleporter messages to this contract. + * + * This function should be overridden by contracts that inherit from this contract. + */ + function _checkTeleporterRegistryAppAccess() internal virtual; + + /** + * @dev Sends a cross chain message using the TeleporterMessenger contract. + * + * The fee amount should be transferred to this contract prior to calling this function. + * The fee amount is then allocated from this contract's token balance to + * Teleporter's allowance to pay for sending the message. + * + * @return `messageID` The unique identifier for the Teleporter message. + */ + function _sendTeleporterMessage( + TeleporterMessageInput memory messageInput + ) internal virtual returns (bytes32) { + ITeleporterMessenger teleporterMessenger = _getTeleporterMessenger(); + // For non-zero fee amounts increase the Teleporter contract's allowance. + if (messageInput.feeInfo.amount > 0) { + require( + messageInput.feeInfo.feeTokenAddress != address(0), + "TeleporterRegistryApp: zero fee token address" + ); + IERC20(messageInput.feeInfo.feeTokenAddress).safeIncreaseAllowance( + address(teleporterMessenger), messageInput.feeInfo.amount + ); + } + return teleporterMessenger.sendCrossChainMessage(messageInput); + } + + /** + * @dev Returns the Teleporter messenger used to send Teleporter messages, + * and checks that the Teleporter messenger is not paused. + * + * By default returns the latest Teleporter messenger, but can be overriden to + * return a Teleporter messenger of a specific version. + */ + function _getTeleporterMessenger() internal view virtual returns (ITeleporterMessenger) { + ITeleporterMessenger teleporter = teleporterRegistry.getLatestTeleporter(); + require( + !isTeleporterAddressPaused(address(teleporter)), + "TeleporterRegistryApp: Teleporter sending paused" + ); + + return teleporter; + } +} diff --git a/icm-contracts/contracts/teleporter/registry/TeleporterRegistryAppUpgradeable.sol b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryAppUpgradeable.sol new file mode 100644 index 000000000..580d6d05a --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryAppUpgradeable.sol @@ -0,0 +1,343 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterRegistry} from "./TeleporterRegistry.sol"; +import {ITeleporterReceiver} from "@teleporter/ITeleporterReceiver.sol"; +import {ITeleporterMessenger, TeleporterMessageInput} from "@teleporter/ITeleporterMessenger.sol"; +import {ContextUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ContextUpgradeable.sol"; +import {ReentrancyGuardUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ReentrancyGuardUpgradeable.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; + +/** + * @dev TeleporterRegistryAppUpgradeable provides upgrade utility for applications built on top + * of the Teleporter protocol by integrating with the {TeleporterRegistry}. + * + * This contract is intended to be inherited by other contracts that wish to use the + * upgrade mechanism. It provides an interface that restricts access to only Teleporter + * versions that are greater than or equal to `minTeleporterVersion`. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract TeleporterRegistryAppUpgradeable is + Initializable, + ContextUpgradeable, + ITeleporterReceiver, + ReentrancyGuardUpgradeable +{ + using SafeERC20 for IERC20; + + // solhint-disable private-vars-leading-underscore + /** + * @dev Namespace storage slots following the ERC-7201 standard to prevent + * storage collisions between upgradeable contracts. + * @custom:storage-location erc7201:teleporter.storage.TeleporterRegistryApp + */ + struct TeleporterRegistryAppStorage { + // The Teleporter registry contract manages different Teleporter contract versions. + TeleporterRegistry _teleporterRegistry; + /** + * @dev A mapping that keeps track of paused Teleporter addresses. + */ + mapping(address teleporterAddress => bool paused) _pausedTeleporterAddresses; + /** + * @dev The minimum required Teleporter version that the contract is allowed + * to receive messages from. Should only be updated by `_setMinTeleporterVersion` + */ + uint256 _minTeleporterVersion; + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Storage slot computed based off ERC-7201 formula + * keccak256(abi.encode(uint256(keccak256("teleporter.storage.TeleporterRegistryApp")) - 1)) & ~bytes32(uint256(0xff)); + */ + bytes32 public constant TELEPORTER_REGISTRY_APP_STORAGE_LOCATION = + 0xde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00; + + /** + * @dev Emitted when `minTeleporterVersion` is updated. + */ + event MinTeleporterVersionUpdated( + uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion + ); + + /** + * @dev Emitted when a Teleporter address is paused. + */ + event TeleporterAddressPaused(address indexed teleporterAddress); + + /** + * @dev Emitted when a Teleporter address is unpaused. + */ + event TeleporterAddressUnpaused(address indexed teleporterAddress); + + function _getTeleporterRegistryAppStorage() + private + pure + returns (TeleporterRegistryAppStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := TELEPORTER_REGISTRY_APP_STORAGE_LOCATION + } + } + + /** + * @dev Initializes the {TeleporterRegistryApp} contract by getting `teleporterRegistry` + * instance and setting `_minTeleporterVersion`. + * @param teleporterRegistryAddress The address of the Teleporter registry contract. + * The Teleporter registry contract should be deployed, and have at least one Teleporter version. + * @param minTeleporterVersion The minimum Teleporter version allowed for delivering messages. + * The minimum version should be less than or equal to the latest Teleporter version, and greater than 0. + */ + // solhint-disable ordering + // solhint-disable-next-line func-name-mixedcase + function __TeleporterRegistryApp_init( + address teleporterRegistryAddress, + uint256 minTeleporterVersion + ) internal onlyInitializing { + __ReentrancyGuard_init(); + __Context_init(); + __TeleporterRegistryApp_init_unchained(teleporterRegistryAddress, minTeleporterVersion); + } + + // solhint-disable-next-line func-name-mixedcase + function __TeleporterRegistryApp_init_unchained( + address teleporterRegistryAddress, + uint256 minTeleporterVersion + ) internal onlyInitializing { + require( + teleporterRegistryAddress != address(0), + "TeleporterRegistryApp: zero Teleporter registry address" + ); + + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + TeleporterRegistry registry = TeleporterRegistry(teleporterRegistryAddress); + require(registry.latestVersion() > 0, "TeleporterRegistryApp: invalid Teleporter registry"); + $._teleporterRegistry = registry; + _setMinTeleporterVersion(minTeleporterVersion); + } + // solhint-enable ordering + + /** + * @dev See {ITeleporterReceiver-receiveTeleporterMessage} + * `nonReentrant` is a reentrancy guard that protects against multiple versions of the + * TeleporterMessengerContract delivering a message in the same call. Any internal calls + * will not be able to call functions also marked with `nonReentrant`. + * + * Requirements: + * + * - `_msgSender()` must be a Teleporter version greater than or equal to `minTeleporterVersion`. + */ + function receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes calldata message + ) external nonReentrant { + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + // Checks that `_msgSender()` matches a Teleporter version greater than or equal to `minTeleporterVersion`. + require( + $._teleporterRegistry.getVersionFromAddress(_msgSender()) >= $._minTeleporterVersion, + "TeleporterRegistryApp: invalid Teleporter sender" + ); + + // Check against the paused Teleporter addresses. + require( + !_isTeleporterAddressPaused($, _msgSender()), + "TeleporterRegistryApp: Teleporter address paused" + ); + + _receiveTeleporterMessage(sourceBlockchainID, originSenderAddress, message); + } + + /** + * @dev Checks if a Teleporter address is paused. + */ + function isTeleporterAddressPaused( + address teleporterAddress + ) external view virtual returns (bool) { + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + return _isTeleporterAddressPaused($, teleporterAddress); + } + + /** + * @dev Updates the minimum Teleporter version allowed for delivering Teleporer messages + * to this contract. + * + * To prevent anyone from being able to call this function, which would disallow messages + * from old Teleporter versions from being received, this function should be safeguarded with access + * controls. This is done by overriding the implementation of {_checkTeleporterRegistryAppAccess}. + */ + function updateMinTeleporterVersion( + uint256 version + ) public virtual { + _checkTeleporterRegistryAppAccess(); + _setMinTeleporterVersion(version); + } + + /** + * @dev Pauses a Teleporter address from interacting with this contract. + * After pausing a Teleporter address, it will no longer be able to deliver messages + * to this contract, and this contract will not send messages through that Teleporter address. + * The address does not need to be registered with the Teleporter registry. + * Emits a {TeleporterAddressPaused} event if successfully paused. + * Requirements: + * + * - `_msgSender()` must have Teleporter upgrade access. + * - `teleporterAddress` is not the zero address. + * - `teleporterAddress` is not already paused. + */ + function pauseTeleporterAddress( + address teleporterAddress + ) public virtual { + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + _checkTeleporterRegistryAppAccess(); + require(teleporterAddress != address(0), "TeleporterRegistryApp: zero Teleporter address"); + require( + !_isTeleporterAddressPaused($, teleporterAddress), + "TeleporterRegistryApp: address already paused" + ); + $._pausedTeleporterAddresses[teleporterAddress] = true; + emit TeleporterAddressPaused(teleporterAddress); + } + + /** + * @dev Unpauses a Teleporter address from interacting with this contract. + * After unpausing a Teleporter address, it will again be able to deliver messages + * to this contract, and this contract can send messages through that Teleporter address. + * The address does not need to be registered with the Teleporter registry. + * Emits a {TeleporterAddressUnpaused} event if successfully unpaused. + * Requirements: + * + * - `_msgSender()` must have Teleporter upgrade access. + * - `teleporterAddress` is not the zero address. + * - `teleporterAddress` is already paused. + */ + function unpauseTeleporterAddress( + address teleporterAddress + ) public virtual { + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + _checkTeleporterRegistryAppAccess(); + require(teleporterAddress != address(0), "TeleporterRegistryApp: zero Teleporter address"); + require( + _isTeleporterAddressPaused($, teleporterAddress), + "TeleporterRegistryApp: address not paused" + ); + $._pausedTeleporterAddresses[teleporterAddress] = false; + emit TeleporterAddressUnpaused(teleporterAddress); + } + + /** + * @dev Public getter for `_minTeleporterVersion`. + */ + function getMinTeleporterVersion() public view returns (uint256) { + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + return $._minTeleporterVersion; + } + + /** + * @dev Sets the minimum Teleporter version allowed for delivering Teleporter messages. + * Emits a {MinTeleporterVersionUpdated} event if the minimum Teleporter version was updated. + * Requirements: + * + * - `version` must be less than or equal to the latest Teleporter version. + * - `version` must be greater than the current minimum Teleporter version. + * + */ + function _setMinTeleporterVersion( + uint256 version + ) internal virtual { + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + uint256 latestTeleporterVersion = $._teleporterRegistry.latestVersion(); + uint256 oldMinTeleporterVersion = $._minTeleporterVersion; + + require( + version <= latestTeleporterVersion, "TeleporterRegistryApp: invalid Teleporter version" + ); + require( + version > oldMinTeleporterVersion, + "TeleporterRegistryApp: not greater than current minimum version" + ); + + $._minTeleporterVersion = version; + emit MinTeleporterVersionUpdated(oldMinTeleporterVersion, version); + } + + /** + * @dev Receives Teleporter messages and handles accordingly. + * This function should be overridden by contracts that inherit from this contract. + */ + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message + ) internal virtual; + + /** + * @dev Checks that the caller has access to update the minimum Teleporter version + * allowed for delivering Teleporter messages to this contract. + * + * This function should be overridden by contracts that inherit from this contract. + */ + function _checkTeleporterRegistryAppAccess() internal virtual; + + /** + * @dev Sends a cross chain message using the TeleporterMessenger contract. + * + * The fee amount should be transferred to this contract prior to calling this function. + * The fee amount is then allocated from this contract's token balance to + * Teleporter's allowance to pay for sending the message. + * + * @return `messageID` The unique identifier for the Teleporter message. + */ + function _sendTeleporterMessage( + TeleporterMessageInput memory messageInput + ) internal virtual returns (bytes32) { + ITeleporterMessenger teleporterMessenger = _getTeleporterMessenger(); + // For non-zero fee amounts increase the Teleporter contract's allowance. + if (messageInput.feeInfo.amount > 0) { + require( + messageInput.feeInfo.feeTokenAddress != address(0), + "TeleporterRegistryApp: zero fee token address" + ); + IERC20(messageInput.feeInfo.feeTokenAddress).safeIncreaseAllowance( + address(teleporterMessenger), messageInput.feeInfo.amount + ); + } + return teleporterMessenger.sendCrossChainMessage(messageInput); + } + + /** + * @dev Returns the Teleporter messenger used to send Teleporter messages, + * and checks that the Teleporter messenger is not paused. + * + * By default returns the latest Teleporter messenger, but can be overriden to + * return a Teleporter messenger of a specific version. + */ + function _getTeleporterMessenger() internal view virtual returns (ITeleporterMessenger) { + TeleporterRegistryAppStorage storage $ = _getTeleporterRegistryAppStorage(); + ITeleporterMessenger teleporter = $._teleporterRegistry.getLatestTeleporter(); + require( + !_isTeleporterAddressPaused($, address(teleporter)), + "TeleporterRegistryApp: Teleporter sending paused" + ); + + return teleporter; + } + + function _isTeleporterAddressPaused( + TeleporterRegistryAppStorage storage $, + address teleporterAddress + ) internal view returns (bool) { + return $._pausedTeleporterAddresses[teleporterAddress]; + } +} diff --git a/icm-contracts/contracts/teleporter/registry/TeleporterRegistryOwnableApp.sol b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryOwnableApp.sol new file mode 100644 index 000000000..20fcf3f1a --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryOwnableApp.sol @@ -0,0 +1,37 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterRegistryApp} from "./TeleporterRegistryApp.sol"; +import {Ownable} from "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; + +/** + * @dev Contract that inherits {TeleporterRegistryApp} and allows + * only owners of the contract to update the minimum Teleporter version or + * pause and unpause specific Teleporter versions. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract TeleporterRegistryOwnableApp is TeleporterRegistryApp, Ownable { + constructor( + address teleporterRegistryAddress, + address initialOwner, + uint256 minTeleporterVersion + ) + TeleporterRegistryApp(teleporterRegistryAddress, minTeleporterVersion) + Ownable(initialOwner) + {} + + /** + * @dev See {TeleporterRegistryApp-_checkTeleporterRegistryAppAccess} + * + * Checks that the caller is the owner of the contract for updating {minTeleporterVersion}, + * and pausing/unpausing specific Teleporter version interactions. + */ + function _checkTeleporterRegistryAppAccess() internal view virtual override { + _checkOwner(); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/TeleporterRegistryOwnableAppUpgradeable.sol b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryOwnableAppUpgradeable.sol new file mode 100644 index 000000000..ef97ae015 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/TeleporterRegistryOwnableAppUpgradeable.sol @@ -0,0 +1,45 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterRegistryAppUpgradeable} from "./TeleporterRegistryAppUpgradeable.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; + +/** + * @dev Contract that inherits {TeleporterRegistryAppUpgradeable} and allows + * only owners of the contract to update the minimum Teleporter version or + * pause and unpause specific Teleporter versions. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract TeleporterRegistryOwnableAppUpgradeable is + TeleporterRegistryAppUpgradeable, + OwnableUpgradeable +{ + // solhint-disable-next-line func-name-mixedcase + function __TeleporterRegistryOwnableApp_init( + address teleporterRegistryAddress, + address initialOwner, + uint256 minTeleporterVersion + ) internal onlyInitializing { + __TeleporterRegistryApp_init(teleporterRegistryAddress, minTeleporterVersion); + __Ownable_init(initialOwner); + } + + // solhint-disable-next-line func-name-mixedcase, no-empty-blocks, func-name-mixedcase + function _TeleporterRegistryOwnableApp_init_unchained() internal onlyInitializing {} + + /** + * @dev See {TeleporterRegistryAppUpgradeable-_checkTeleporterRegistryAppAccess} + * + * Checks that the caller is the owner of the contract for updating {minTeleporterVersion}, + * and pausing/unpausing specific Teleporter version interactions. + */ + function _checkTeleporterRegistryAppAccess() internal view virtual override { + _checkOwner(); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/UPGRADING.md b/icm-contracts/contracts/teleporter/registry/UPGRADING.md new file mode 100644 index 000000000..5b3d469f3 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/UPGRADING.md @@ -0,0 +1,49 @@ +# Upgrading TeleporterMessenger + +This document outlines the high-level steps necessary to upgrade `TeleporterMessenger` as an Avalanche L1 operator, a relayer operator, and a dApp admin. As a reference, the [Teleporter Registry test suite](../../../tests/flows/teleporter_registry.go) implements the steps described in a test environment. + +## Register a New TeleporterMessenger Version + +Once a new `TeleporterMessenger` contract instance is [deployed](../../../utils/contract-deployment/README.md), the `addProtocolVersion` method of [TeleporterRegistry.sol](./TeleporterRegistry.sol) must be called. This method is only callable if the associated ICM message was sent via an off-chain ICM message, which is provided by a validator's chain config. + +The steps to do so are as follows: + +1. Construct the unsigned ICM message bytes: + + a. Pack the ICM payload to be parsed by `addProtocolVersion`. This is a tuple of `(ProtocolRegistryEntry, address)`, where the `ProtocolRegistryEntry` specifies the new `TeleporterMessenger` contract address and the version, and the `address` specifies the `TeleporterRegistry` contract address that the new `TeleporterMessenger` version will be registered with. + + b. Pack the ICM payload as an [AddressedCall](https://github.com/ava-labs/avalanchego/blob/v1.11.3/vms/platformvm/warp/payload/addressed_call.go#L15), with the source address set to the zero address. This is how `addProtocolVersion` identifies this message as an off-chain ICM message. + + c. Pack the `AddressedCall` message into an [unsigned ICM message](https://github.com/ava-labs/avalanchego/blob/v1.11.3/vms/platformvm/warp/unsigned_message.go#L14), specifying the blockchain ID that `TeleporterRegistry` and the new `TeleporterMessenger` are deployed to. + +2. Populate the "warp-off-chain-messages" field of each validator node's chain config with the hex-encoded unsigned ICM message bytes. + +3. Restart the node to mark the off-chain ICM message as eligible for signing by the validator. + +To actually register the new `TeleporterMessenger` version with the registry, the validators must be queried for their signature of the message, the signatures aggregated, and a signed ICM message created to be included in the transaction that calls `addProtocolVersion`. As an example, [ICM Relayer](https://github.com/ava-labs/icm-services) provides this functionality. The following steps illustrate how to use ICM Relayer to register the new `TeleporterMessenger` version. + +1. Construct a "manual-warp-messages" entry in the ICM Relayer configuration file, using the following values: + + a. "unsigned-message-bytes": the hex-encoded unsigned ICM message bytes derived above. + + b. "source-blockchain-id": the blockchain ID that that `TeleporterRegistry` and the new `TeleporterMessenger` are deployed to. + + c. "destination-blockchain-id": the blockchain ID that that `TeleporterRegistry` and the new `TeleporterMessenger` are deployed to. + + d. "source-address": the zero address, "0x0000000000000000000000000000000000000000". This is the "source" address for off-chain ICM messages. + +2. Add the `TeleporterRegistry` as a supported message type by adding the following entry to the list of "message-contracts": + + a. Set the key to the zero address, "0x0000000000000000000000000000000000000000". + + b. Set the value as the following, populating the : + ```json + { + "message-format": "off-chain-registry", + "settings": { + "teleporter-registry-address": "" + } + } + ``` + +3. Restart the relayer. On startup, it will query the validator nodes for their BLS signatures on the off-chain ICM message, construct an aggregate signature and signed ICM message, and use it to call `addProtocolVersion` in the registry. diff --git a/icm-contracts/contracts/teleporter/registry/tests/BaseTeleporterRegistryAppTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/BaseTeleporterRegistryAppTests.t.sol new file mode 100644 index 000000000..9c70d48e7 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/BaseTeleporterRegistryAppTests.t.sol @@ -0,0 +1,196 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterRegistryAppUpgradeable} from "../TeleporterRegistryAppUpgradeable.sol"; +import {TeleporterRegistryApp} from "../TeleporterRegistryApp.sol"; +import {TeleporterRegistryTest} from "./TeleporterRegistryTests.t.sol"; +import {ITeleporterMessenger, TeleporterMessageInput} from "@teleporter/ITeleporterMessenger.sol"; +import {TeleporterMessenger} from "@teleporter/TeleporterMessenger.sol"; +import {UnitTestMockERC20} from "@mocks/UnitTestMockERC20.sol"; + +contract ExampleRegistryAppUpgradeable is TeleporterRegistryAppUpgradeable { + function initialize( + address teleporterRegistryAddress, + uint256 minTeleporterVersion + ) public initializer { + __TeleporterRegistryApp_init(teleporterRegistryAddress, minTeleporterVersion); + } + + function setMinTeleporterVersion( + uint256 version + ) public { + _setMinTeleporterVersion(version); + } + + function sendTeleporterMessage( + TeleporterMessageInput calldata messageInput + ) public { + _sendTeleporterMessage(messageInput); + } + + function getTeleporterMessenger() public view returns (ITeleporterMessenger) { + return _getTeleporterMessenger(); + } + + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message // solhint-disable-next-line no-empty-blocks + ) internal override {} + + // solhint-disable-next-line no-empty-blocks + function _checkTeleporterRegistryAppAccess() internal override {} +} + +contract ExampleRegistryApp is TeleporterRegistryApp { + constructor( + address teleporterRegistryAddress, + uint256 minTeleporterVersion + ) TeleporterRegistryApp(teleporterRegistryAddress, minTeleporterVersion) {} + + function setMinTeleporterVersion( + uint256 version + ) public { + _setMinTeleporterVersion(version); + } + + function sendTeleporterMessage( + TeleporterMessageInput calldata messageInput + ) public { + _sendTeleporterMessage(messageInput); + } + + function getTeleporterMessenger() public view returns (ITeleporterMessenger) { + return _getTeleporterMessenger(); + } + + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message // solhint-disable-next-line no-empty-blocks + ) internal override {} + + // solhint-disable-next-line no-empty-blocks + function _checkTeleporterRegistryAppAccess() internal virtual override {} +} + +abstract contract BaseTeleporterRegistryAppTest is TeleporterRegistryTest { + bytes32 public constant DEFAULT_SOURCE_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + bytes32 public constant DEFAULT_DESTINATION_BLOCKCHAIN_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + address public constant DEFAULT_DESTINATION_ADDRESS = 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + address public constant DEFAULT_ORIGIN_ADDRESS = 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + + ExampleRegistryApp public app; + + UnitTestMockERC20 internal _mockFeeAsset; + + event MinTeleporterVersionUpdated( + uint256 indexed oldMinTeleporterVersion, uint256 indexed newMinTeleporterVersion + ); + + event TeleporterAddressPaused(address indexed teleporterAddress); + + event TeleporterAddressUnpaused(address indexed teleporterAddress); + + function setUp() public virtual override { + TeleporterRegistryTest.setUp(); + _addProtocolVersion(teleporterRegistry, teleporterAddress); + _mockFeeAsset = new UnitTestMockERC20(); + TeleporterMessenger(teleporterAddress).initializeBlockchainID(); + } + + function testOnlyAllowedTeleporter() public { + assertEq(app.getMinTeleporterVersion(), 1); + + vm.expectRevert(_formatRegistryErrorMessage("protocol address not found")); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testUpdateMinTeleporterVersion() public { + // First check that calling with initial teleporter address works + assertEq(app.getMinTeleporterVersion(), 1); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Now add new protocol version to registry and update the app's min version + address newTeleporterAddress = address(new TeleporterMessenger()); + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + + _updateMinTeleporterVersionSuccess(app, teleporterRegistry.latestVersion()); + assertEq(app.getMinTeleporterVersion(), 2); + + // Check that calling with the old teleporter address fails + vm.expectRevert(_formatErrorMessage("invalid Teleporter sender")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Check that calling with the new teleporter address works + vm.prank(newTeleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testSetMinTeleporterVersion() public { + uint256 latestVersion = teleporterRegistry.latestVersion(); + + // Check setting for a version > latest version fails + vm.expectRevert(_formatErrorMessage("invalid Teleporter version")); + app.setMinTeleporterVersion(latestVersion + 1); + + // Check setting for a version <= min version fails + uint256 minVersion = app.getMinTeleporterVersion(); + assertEq(minVersion, teleporterRegistry.latestVersion()); + vm.expectRevert(_formatErrorMessage("not greater than current minimum version")); + app.setMinTeleporterVersion(minVersion); + + // Add a new protocol version to the registry + _addProtocolVersion(teleporterRegistry, teleporterAddress); + + // Check setting a new valid minimum version + vm.expectEmit(true, true, true, true, address(app)); + emit MinTeleporterVersionUpdated(latestVersion, latestVersion + 1); + app.setMinTeleporterVersion(teleporterRegistry.latestVersion()); + assertEq(app.getMinTeleporterVersion(), latestVersion + 1); + } + + function _updateMinTeleporterVersionSuccess( + TeleporterRegistryApp app_, + uint256 newMinTeleporterVersion + ) internal virtual { + vm.expectEmit(true, true, true, true, address(app_)); + emit MinTeleporterVersionUpdated(app_.getMinTeleporterVersion(), newMinTeleporterVersion); + app_.updateMinTeleporterVersion(newMinTeleporterVersion); + } + + function _pauseTeleporterAddressSuccess( + TeleporterRegistryApp app_, + address teleporterAddress_ + ) internal virtual { + vm.expectEmit(true, true, true, true, address(app_)); + emit TeleporterAddressPaused(teleporterAddress_); + app_.pauseTeleporterAddress(teleporterAddress_); + } + + function _unpauseTeleporterAddressSuccess( + TeleporterRegistryApp app_, + address teleporterAddress_ + ) internal virtual { + vm.expectEmit(true, true, true, true, address(app_)); + emit TeleporterAddressUnpaused(teleporterAddress_); + app_.unpauseTeleporterAddress(teleporterAddress_); + } + + function _formatErrorMessage( + bytes memory errorMessage + ) internal pure returns (bytes memory) { + return abi.encodePacked("TeleporterRegistryApp: ", errorMessage); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/BaseTeleporterRegistryOwnableAppTest.t.sol b/icm-contracts/contracts/teleporter/registry/tests/BaseTeleporterRegistryOwnableAppTest.t.sol new file mode 100644 index 000000000..5a2a452e9 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/BaseTeleporterRegistryOwnableAppTest.t.sol @@ -0,0 +1,269 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterRegistryOwnableAppUpgradeable} from + "../TeleporterRegistryOwnableAppUpgradeable.sol"; +import {TeleporterRegistryOwnableApp} from "../TeleporterRegistryOwnableApp.sol"; +import {TeleporterRegistryApp} from "../TeleporterRegistryApp.sol"; +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; +import {ITeleporterMessenger, TeleporterMessageInput} from "@teleporter/ITeleporterMessenger.sol"; + +contract ExampleRegistryOwnableAppUpgradeable is TeleporterRegistryOwnableAppUpgradeable { + function initialize( + address teleporterRegistryAddress, + address initialOwner, + uint256 minTeleporterVersion + ) public initializer { + __TeleporterRegistryOwnableApp_init( + teleporterRegistryAddress, initialOwner, minTeleporterVersion + ); + } + + function setMinTeleporterVersion( + uint256 version + ) public { + _setMinTeleporterVersion(version); + } + + function sendTeleporterMessage( + TeleporterMessageInput calldata messageInput + ) public { + _sendTeleporterMessage(messageInput); + } + + function getTeleporterMessenger() public view returns (ITeleporterMessenger) { + return _getTeleporterMessenger(); + } + + function checkTeleporterRegistryAppAccess() public view { + _checkTeleporterRegistryAppAccess(); + } + + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message // solhint-disable-next-line no-empty-blocks + ) internal override {} +} + +contract ExampleRegistryOwnableApp is TeleporterRegistryOwnableApp { + constructor( + address teleporterRegistryAddress, + address initialOwner, + uint256 minTeleporterVersion + ) TeleporterRegistryOwnableApp(teleporterRegistryAddress, initialOwner, minTeleporterVersion) {} + + function setMinTeleporterVersion( + uint256 version + ) public { + _setMinTeleporterVersion(version); + } + + function sendTeleporterMessage( + TeleporterMessageInput calldata messageInput + ) public { + _sendTeleporterMessage(messageInput); + } + + function getTeleporterMessenger() public view returns (ITeleporterMessenger) { + return _getTeleporterMessenger(); + } + + function checkTeleporterRegistryAppAccess() public view { + _checkTeleporterRegistryAppAccess(); + } + + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message // solhint-disable-next-line no-empty-blocks + ) internal override {} +} + +abstract contract BaseTeleporterRegistryOwnableAppTest is BaseTeleporterRegistryAppTest { + address public constant MOCK_INVALID_OWNER_ADDRESS = 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + address public constant DEFAULT_OWNER_ADDRESS = 0x1234512345123451234512345123451234512345; + + ExampleRegistryOwnableApp public ownerApp; + + function setUp() public virtual override { + BaseTeleporterRegistryAppTest.setUp(); + } + + function testOwnerUpdateMinTeleporterVersion() public { + uint256 minTeleporterVersion = ownerApp.getMinTeleporterVersion(); + _addProtocolVersion(teleporterRegistry, teleporterAddress); + + // Check that call to update minimum Teleporter version reverts for non-owners + vm.prank(MOCK_INVALID_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, MOCK_INVALID_OWNER_ADDRESS + ) + ); + ownerApp.updateMinTeleporterVersion(minTeleporterVersion + 1); + + // Check that minimum Teleporter version was not updated + assertEq(ownerApp.getMinTeleporterVersion(), minTeleporterVersion); + + // Check that call to update minimum Teleporter version succeeds for owners + _updateMinTeleporterVersionSuccess(ownerApp, minTeleporterVersion + 1); + + assertEq(ownerApp.getMinTeleporterVersion(), minTeleporterVersion + 1); + } + + function testOwnerTransfer() public { + uint256 minTeleporterVersion = ownerApp.getMinTeleporterVersion(); + _addProtocolVersion(teleporterRegistry, teleporterAddress); + + // Check that call to transfer ownership reverts for non-owners + vm.prank(MOCK_INVALID_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, MOCK_INVALID_OWNER_ADDRESS + ) + ); + ownerApp.transferOwnership(address(0)); + + // Check that ownership was not transferred + assertEq(ownerApp.owner(), DEFAULT_OWNER_ADDRESS); + + // Check that call for non owners reverts + vm.prank(MOCK_INVALID_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, MOCK_INVALID_OWNER_ADDRESS + ) + ); + ownerApp.updateMinTeleporterVersion(minTeleporterVersion + 1); + + // Check that after ownership transfer call succeeds + address newOwner = address(0x123); + vm.prank(DEFAULT_OWNER_ADDRESS); + ownerApp.transferOwnership(newOwner); + vm.prank(newOwner); + ownerApp.updateMinTeleporterVersion(minTeleporterVersion + 1); + + // Check that call with old owner reverts + vm.prank(DEFAULT_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, DEFAULT_OWNER_ADDRESS + ) + ); + ownerApp.updateMinTeleporterVersion(minTeleporterVersion + 1); + } + + function testRenounceOwnership() public { + // Check that call to renounce ownership reverts for non-owners + vm.prank(MOCK_INVALID_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, MOCK_INVALID_OWNER_ADDRESS + ) + ); + ownerApp.renounceOwnership(); + + // Check that ownership was not renounced + assertEq(ownerApp.owner(), DEFAULT_OWNER_ADDRESS); + vm.prank(DEFAULT_OWNER_ADDRESS); + _addProtocolVersion(teleporterRegistry, teleporterAddress); + uint256 latestVersion = teleporterRegistry.latestVersion(); + // Check that update Teleporter version call for owner succeeds + _updateMinTeleporterVersionSuccess(ownerApp, latestVersion); + + // Check that after ownership renounce call reverts + vm.prank(DEFAULT_OWNER_ADDRESS); + ownerApp.renounceOwnership(); + + vm.prank(DEFAULT_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, DEFAULT_OWNER_ADDRESS + ) + ); + ownerApp.updateMinTeleporterVersion(latestVersion); + } + + function testPauseTeleporterAccess() public { + // First pause the Teleporter address + vm.prank(DEFAULT_OWNER_ADDRESS); + _pauseTeleporterAddressSuccess(ownerApp, teleporterAddress); + + // Try to unpause the Teleporter address from non-owner account + vm.prank(MOCK_INVALID_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, MOCK_INVALID_OWNER_ADDRESS + ) + ); + ownerApp.unpauseTeleporterAddress(teleporterAddress); + + // Check that the Teleporter address is still paused + vm.prank(teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + ownerApp.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Unpause the Teleporter address from owner account + vm.prank(DEFAULT_OWNER_ADDRESS); + _unpauseTeleporterAddressSuccess(ownerApp, teleporterAddress); + + // Check that the Teleporter address can now deliver messages + vm.prank(teleporterAddress); + ownerApp.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testOwnerUpgradeAccess() public { + // Check that call to check upgrade access reverts for non-owners + vm.prank(MOCK_INVALID_OWNER_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, MOCK_INVALID_OWNER_ADDRESS + ) + ); + ownerApp.checkTeleporterRegistryAppAccess(); + + // Check that call to check upgrade access succeeds for owners + vm.prank(DEFAULT_OWNER_ADDRESS); + ownerApp.checkTeleporterRegistryAppAccess(); + } + + function testInitalOwner() public { + // Create a new Ownable app with a passed in teleporterManager + ExampleRegistryOwnableAppUpgradeable newOwnerApp = + new ExampleRegistryOwnableAppUpgradeable(); + newOwnerApp.initialize( + address(teleporterRegistry), DEFAULT_OWNER_ADDRESS, teleporterRegistry.latestVersion() + ); + + // Check that the teleporterManager is set correctly + assertEq(newOwnerApp.owner(), DEFAULT_OWNER_ADDRESS); + vm.prank(DEFAULT_OWNER_ADDRESS); + newOwnerApp.checkTeleporterRegistryAppAccess(); + + // Check that address(this) as the caller is not by default owner + assertFalse(newOwnerApp.owner() == address(this)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, address(this) + ) + ); + newOwnerApp.checkTeleporterRegistryAppAccess(); + } + + function _updateMinTeleporterVersionSuccess( + TeleporterRegistryApp app_, + uint256 newMinTeleporterVersion + ) internal virtual override { + vm.expectEmit(true, true, true, true, address(app_)); + emit MinTeleporterVersionUpdated(app_.getMinTeleporterVersion(), newMinTeleporterVersion); + vm.prank(DEFAULT_OWNER_ADDRESS); + app_.updateMinTeleporterVersion(newMinTeleporterVersion); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/GetTeleporterMessengerTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/GetTeleporterMessengerTests.t.sol new file mode 100644 index 000000000..c8d1e1a1e --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/GetTeleporterMessengerTests.t.sol @@ -0,0 +1,71 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import {ITeleporterMessenger} from "@teleporter/ITeleporterMessenger.sol"; +import {TeleporterMessenger} from "@teleporter/TeleporterMessenger.sol"; + +abstract contract GetTeleporterMessengerTest is BaseTeleporterRegistryAppTest { + function testGetPausedTeleporterMessenger() public { + _pauseTeleporterAddressSuccess(app, teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter sending paused")); + app.getTeleporterMessenger(); + } + + function testGetUnpausedTeleporterMessenger() public { + _pauseTeleporterAddressSuccess(app, teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter sending paused")); + app.getTeleporterMessenger(); + + // Unpause the Teleporter address, and now we should getTeleporterMessenger successfully + _unpauseTeleporterAddressSuccess(app, teleporterAddress); + app.getTeleporterMessenger(); + } + + function testGetNewTeleporterMessenger() public { + // Pause the current latest version of Teleporter + + _pauseTeleporterAddressSuccess(app, teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter sending paused")); + app.getTeleporterMessenger(); + + // Add a new version of Teleporter, and make sure we can get + // the new Teleporter successfully. + address newTeleporterAddress = address(new TeleporterMessenger()); + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + ITeleporterMessenger messenger = app.getTeleporterMessenger(); + assertEq(address(messenger), newTeleporterAddress); + assertEq( + teleporterRegistry.getVersionFromAddress(address(messenger)), + teleporterRegistry.latestVersion() + ); + } + + function testPauseNonLatestTeleporter() public { + address newTeleporterAddress = address(new TeleporterMessenger()); + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + + // Pause a non-latest version of Teleporter + _pauseTeleporterAddressSuccess(app, teleporterAddress); + + // Make sure we can still get the latest version of Teleporter for sending + ITeleporterMessenger messenger = app.getTeleporterMessenger(); + assertEq(address(messenger), newTeleporterAddress); + assertEq( + teleporterRegistry.getVersionFromAddress(address(messenger)), + teleporterRegistry.latestVersion() + ); + } + + function testGetTeleporterMessengerBasic() public view { + ITeleporterMessenger messenger = app.getTeleporterMessenger(); + assertEq( + teleporterRegistry.getVersionFromAddress(address(messenger)), + teleporterRegistry.latestVersion() + ); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/NonReentrantTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/NonReentrantTests.t.sol new file mode 100644 index 000000000..3b5952887 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/NonReentrantTests.t.sol @@ -0,0 +1,152 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterRegistryAppUpgradeable} from "../TeleporterRegistryAppUpgradeable.sol"; +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import { + ITeleporterMessenger, + TeleporterMessage, + TeleporterMessageReceipt +} from "@teleporter/ITeleporterMessenger.sol"; +import {WarpMessage} from "@subnet-evm/IWarpMessenger.sol"; +import {TeleporterMessenger} from "@teleporter/TeleporterMessenger.sol"; + +uint32 constant warpMessageIndex = 2; + +contract NonReentrantUpgradeableApp is TeleporterRegistryAppUpgradeable { + function initialize( + address teleporterRegistryAddress, + uint256 minTeleporterVersion + ) public initializer { + __TeleporterRegistryApp_init(teleporterRegistryAddress, minTeleporterVersion); + } + + function setMinTeleporterVersion( + uint256 version + ) public { + _setMinTeleporterVersion(version); + } + + function getTeleporterMessenger() public view returns (ITeleporterMessenger) { + return _getTeleporterMessenger(); + } + + // Calls receiveCrossChainMessage on the latest TeleporterMessenger Contract. + // The Warp Precompile is mocked to return a message that will call + // TeleporterRegistryAppUpgradeable.receiveTeleporterMessage which should revert because it is + // non-reentrant. + function _receiveTeleporterMessage(bytes32, address, bytes memory) internal override { + // Call `receiveCrossChainMessage` of the latest version of Teleporter + getTeleporterMessenger().receiveCrossChainMessage(warpMessageIndex, address(this)); + } + + // solhint-disable-next-line no-empty-blocks + function _checkTeleporterRegistryAppAccess() internal override {} +} + +// The flow for the tests below is as follows: +// NonreentrantUpgradeableApp::receiveTeleporterMessage -> +// NonreentrantUpgradeableApp::_receiveTeleporterMessage -> +// TeleporterMessenger::receiveCrossChainMessage -> +// NonreentrantUpgradeableApp::receiveTeleporterMessage +// The last step should revert because receiveTeleporterMessage (contained in +// TeleporterRegistryAppUpgradeable) is non-reentrant. +abstract contract NonReentrantTest is BaseTeleporterRegistryAppTest { + bytes public constant DEFAULT_MESSAGE = bytes(hex"1234"); + uint256 public constant DEFAULT_REQUIRED_GAS_LIMIT = 1e6; + + NonReentrantUpgradeableApp public nonReentrantApp; + + event MessageExecutionFailed( + bytes32 indexed messageID, bytes32 indexed originBlockchainID, TeleporterMessage message + ); + + event MessageExecuted(bytes32 indexed messageID, bytes32 indexed originBlockchainID); + + function setUp() public virtual override { + nonReentrantApp = new NonReentrantUpgradeableApp(); + nonReentrantApp.initialize(address(teleporterRegistry), teleporterRegistry.latestVersion()); + } + + function testNonReentrantSameTeleporter() public { + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 987, + originSenderAddress: DEFAULT_ORIGIN_ADDRESS, + destinationBlockchainID: MOCK_BLOCK_CHAIN_ID, + destinationAddress: address(nonReentrantApp), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: DEFAULT_MESSAGE + }); + WarpMessage memory warpMessage = WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: teleporterAddress, + payload: abi.encode(messageToReceive) + }); + + // Same index as in NonreentrantUpgradeableApp._receiveTeleporterMessage() + _mockGetVerifiedWarpMessage(warpMessageIndex, warpMessage, true); + + bytes32 messageID = TeleporterMessenger(teleporterAddress).calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, MOCK_BLOCK_CHAIN_ID, messageToReceive.messageNonce + ); + + vm.expectEmit(true, true, true, true, address(teleporterAddress)); + emit MessageExecutionFailed(messageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + + vm.prank(teleporterAddress); + nonReentrantApp.receiveTeleporterMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, DEFAULT_MESSAGE + ); + } + + function testNonReentrantDifferentTeleporter() public { + TeleporterMessenger teleporterV2 = new TeleporterMessenger(); + teleporterV2.initializeBlockchainID(); + _addProtocolVersion(teleporterRegistry, address(teleporterV2)); + + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 987, + originSenderAddress: DEFAULT_ORIGIN_ADDRESS, + destinationBlockchainID: MOCK_BLOCK_CHAIN_ID, + destinationAddress: address(nonReentrantApp), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: DEFAULT_MESSAGE + }); + WarpMessage memory warpMessage = WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(teleporterV2), + payload: abi.encode(messageToReceive) + }); + + // Same index as in NonreentrantUpgradeableApp._receiveTeleporterMessage() + _mockGetVerifiedWarpMessage(warpMessageIndex, warpMessage, true); + + vm.expectCall( + address(teleporterV2), + abi.encodeCall( + ITeleporterMessenger.receiveCrossChainMessage, + (warpMessageIndex, address(nonReentrantApp)) + ) + ); + + bytes32 messageID = TeleporterMessenger(teleporterV2).calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, MOCK_BLOCK_CHAIN_ID, messageToReceive.messageNonce + ); + + vm.expectEmit(true, true, true, true, address(teleporterV2)); + emit MessageExecutionFailed(messageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + + vm.prank(teleporterAddress); + nonReentrantApp.receiveTeleporterMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, DEFAULT_MESSAGE + ); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/PauseTeleporterAddressTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/PauseTeleporterAddressTests.t.sol new file mode 100644 index 000000000..45ab1f463 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/PauseTeleporterAddressTests.t.sol @@ -0,0 +1,81 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import {TeleporterMessenger} from "@teleporter/TeleporterMessenger.sol"; + +abstract contract PauseTeleporterAddressTest is BaseTeleporterRegistryAppTest { + function testPauseTeleporterAddressBasic() public { + // Check that the teleporterAddress is not paused initially + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + // Check that teleporterAddress can not deliver messages once paused + _pauseTeleporterAddressSuccess(app, teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testAlreadyPausedTeleporterAddress() public { + // Check that teleporterAddress can not deliver messages once paused + _pauseTeleporterAddressSuccess(app, teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + // Check that teleporterAddress can not be paused again + vm.expectRevert(_formatErrorMessage("address already paused")); + app.pauseTeleporterAddress(teleporterAddress); + } + + function testPauseMultipleVersions() public { + // Since a Teleporter address can be registered with multiple versions, + // when pausing a Teleporter address, we should pause all versions of that address. + + // Add the same Teleporter address to the registry with a different version + _addProtocolVersion(teleporterRegistry, teleporterAddress); + + // Check that the teleporterAddress is not paused initially + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Check that teleporterAddress can not deliver messages once paused + _pauseTeleporterAddressSuccess(app, teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Check that after updating mininum Teleporter version, the address is still paused + _updateMinTeleporterVersionSuccess(app, teleporterRegistry.latestVersion()); + vm.prank(teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testPauseBeforeRegister() public { + // Check that a Teleporter address can be paused before it is registered with the registry + + // Create a new Teleporter address that is not registered with the registry + address newTeleporterAddress = address(new TeleporterMessenger()); + + // Pause the new Teleporter address before it is registered + _pauseTeleporterAddressSuccess(app, newTeleporterAddress); + + // Register the new Teleporter address + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + + // Check that the new Teleporter address is paused + vm.prank(newTeleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testPauseZeroAddress() public { + // Check that a zero address can not be paused + vm.expectRevert(_formatErrorMessage("zero Teleporter address")); + app.pauseTeleporterAddress(address(0)); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/SendTeleporterMessageTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/SendTeleporterMessageTests.t.sol new file mode 100644 index 000000000..0bbac4e9a --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/SendTeleporterMessageTests.t.sol @@ -0,0 +1,120 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import { + ITeleporterMessenger, + TeleporterMessageInput, + TeleporterFeeInfo +} from "@teleporter/ITeleporterMessenger.sol"; +import {IERC20} from "@teleporter/TeleporterMessenger.sol"; + +abstract contract SendTeleporterMessageTest is BaseTeleporterRegistryAppTest { + function testSendTeleporterPaused() public { + // Pause the Teleporter address returned from _getTeleporterMessenger() + address teleporter = address(app.getTeleporterMessenger()); + _pauseTeleporterAddressSuccess(app, teleporter); + + // Check that the app reverts when trying to send a message with paused Teleporter + vm.expectRevert(_formatErrorMessage("Teleporter sending paused")); + app.sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(address(0), 0), + requiredGasLimit: 0, + allowedRelayerAddresses: new address[](0), + message: hex"deadbeef" + }) + ); + } + + function testSendNoFee() public { + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(address(0), 0), + requiredGasLimit: 0, + allowedRelayerAddresses: new address[](0), + message: hex"deadbeef" + }); + vm.mockCall( + address(app.getTeleporterMessenger()), + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (messageInput)), + abi.encode(bytes32(0)) + ); + vm.expectCall( + address(app.getTeleporterMessenger()), + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (messageInput)) + ); + + app.sendTeleporterMessage(messageInput); + } + + function testSendWithFee() public { + uint256 feeAmount = 1; + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(address(_mockFeeAsset), feeAmount), + requiredGasLimit: 0, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + vm.mockCall( + address(app.getTeleporterMessenger()), + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (messageInput)), + abi.encode(bytes32(0)) + ); + vm.expectCall( + address(_mockFeeAsset), + abi.encodeCall(IERC20.allowance, (address(app), address(teleporterAddress))) + ); + vm.expectCall( + address(app.getTeleporterMessenger()), + abi.encodeCall(ITeleporterMessenger.sendCrossChainMessage, (messageInput)) + ); + + app.sendTeleporterMessage(messageInput); + } + + function testInvalidFeeAsset() public { + address invalidFeeAsset = 0xb8be9140D8717f4a8fd7e8ae23C5668bc3A4B39c; + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(invalidFeeAsset, 1), + requiredGasLimit: 0, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + // Expect a call to check for allowance, but because we provide an invalid + // fee asset address, the call will revert. + vm.expectCall( + invalidFeeAsset, + abi.encodeCall(IERC20.allowance, (address(app), address(teleporterAddress))) + ); + vm.expectRevert(); + app.sendTeleporterMessage(messageInput); + } + + function testZeroFeeAsset() public { + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(address(0), 1), + requiredGasLimit: 0, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + vm.expectRevert(_formatErrorMessage("zero fee token address")); + app.sendTeleporterMessage(messageInput); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryAppTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryAppTests.t.sol new file mode 100644 index 000000000..20997ddfc --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryAppTests.t.sol @@ -0,0 +1,114 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {GetTeleporterMessengerTest} from "./GetTeleporterMessengerTests.t.sol"; +import {PauseTeleporterAddressTest} from "./PauseTeleporterAddressTests.t.sol"; +import {UpdateMinTeleporterVersionTest} from "./UpdateMinTeleporterVersionTests.t.sol"; +import {SendTeleporterMessageTest} from "./SendTeleporterMessageTests.t.sol"; +import {UnpauseTeleporterAddressTest} from "./UnpauseTeleporterAddressTests.t.sol"; +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import { + ExampleRegistryApp, + ExampleRegistryAppUpgradeable +} from "./BaseTeleporterRegistryAppTests.t.sol"; +import {NonReentrantTest} from "./NonReentrantTests.t.sol"; +import {TeleporterRegistry, ProtocolRegistryEntry} from "../TeleporterRegistry.sol"; + +contract TeleporterRegistryAppTest is + GetTeleporterMessengerTest, + PauseTeleporterAddressTest, + UpdateMinTeleporterVersionTest, + SendTeleporterMessageTest, + UnpauseTeleporterAddressTest, + NonReentrantTest +{ + function setUp() public virtual override (BaseTeleporterRegistryAppTest, NonReentrantTest) { + BaseTeleporterRegistryAppTest.setUp(); + app = + new ExampleRegistryApp(address(teleporterRegistry), teleporterRegistry.latestVersion()); + NonReentrantTest.setUp(); + } + + function testZeroRegistryAddress() public virtual { + vm.expectRevert(_formatErrorMessage("zero Teleporter registry address")); + app = new ExampleRegistryApp(address(0), 0); + } + + function testInvalidRegistryAddress() public virtual { + // Create a new Teleporter registry with no registered Teleporters + TeleporterRegistry teleporterRegistry = + new TeleporterRegistry(new ProtocolRegistryEntry[](0)); + vm.expectRevert(_formatErrorMessage("invalid Teleporter registry")); + app = new ExampleRegistryApp(address(teleporterRegistry), 0); + } + + function testGreaterThanLatestVersion() public virtual { + uint256 minTeleporterVersion = teleporterRegistry.latestVersion() + 1; + vm.expectRevert(_formatErrorMessage("invalid Teleporter version")); + app = new ExampleRegistryApp(address(teleporterRegistry), minTeleporterVersion); + } + + function testZeroMinTeleporterVersion() public virtual { + vm.expectRevert(_formatErrorMessage("not greater than current minimum version")); + app = new ExampleRegistryApp(address(teleporterRegistry), 0); + } +} + +contract TeleporterRegistryAppUpgradeableTest is TeleporterRegistryAppTest { + function setUp() public virtual override { + TeleporterRegistryAppTest.setUp(); + ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable(); + upgradeableApp.initialize(address(teleporterRegistry), teleporterRegistry.latestVersion()); + app = ExampleRegistryApp(address(upgradeableApp)); + } + + function testZeroRegistryAddress() public override { + ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable(); + vm.expectRevert(_formatErrorMessage("zero Teleporter registry address")); + upgradeableApp.initialize(address(0), 0); + } + + function testInvalidRegistryAddress() public override { + ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable(); + + // Create a new Teleporter registry with no registered Teleporters + TeleporterRegistry teleporterRegistry = + new TeleporterRegistry(new ProtocolRegistryEntry[](0)); + vm.expectRevert(_formatErrorMessage("invalid Teleporter registry")); + upgradeableApp.initialize(address(teleporterRegistry), 0); + } + + function testGreaterThanLatestVersion() public override { + ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable(); + + uint256 minTeleporterVersion = teleporterRegistry.latestVersion() + 1; + vm.expectRevert(_formatErrorMessage("invalid Teleporter version")); + upgradeableApp.initialize(address(teleporterRegistry), minTeleporterVersion); + } + + function testZeroMinTeleporterVersion() public override { + ExampleRegistryAppUpgradeable upgradeableApp = new ExampleRegistryAppUpgradeable(); + + vm.expectRevert(_formatErrorMessage("not greater than current minimum version")); + upgradeableApp.initialize(address(teleporterRegistry), 0); + } + + function testStorageSlot() public { + assertEq( + _erc7201StorageSlot("TeleporterRegistryApp"), + new ExampleRegistryAppUpgradeable().TELEPORTER_REGISTRY_APP_STORAGE_LOCATION() + ); + } + + function _erc7201StorageSlot( + bytes memory storageName + ) private pure returns (bytes32) { + return keccak256( + abi.encode(uint256(keccak256(abi.encodePacked("teleporter.storage.", storageName))) - 1) + ) & ~bytes32(uint256(0xff)); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryOwnableAppTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryOwnableAppTests.t.sol new file mode 100644 index 000000000..5b27fa754 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryOwnableAppTests.t.sol @@ -0,0 +1,53 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + BaseTeleporterRegistryOwnableAppTest, + ExampleRegistryOwnableApp, + ExampleRegistryOwnableAppUpgradeable +} from "./BaseTeleporterRegistryOwnableAppTest.t.sol"; +import {ExampleRegistryApp} from "./BaseTeleporterRegistryAppTests.t.sol"; +import {Ownable} from "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; + +contract TeleporterRegistryOwnableAppTest is BaseTeleporterRegistryOwnableAppTest { + function setUp() public virtual override { + BaseTeleporterRegistryOwnableAppTest.setUp(); + ownerApp = new ExampleRegistryOwnableApp( + address(teleporterRegistry), DEFAULT_OWNER_ADDRESS, teleporterRegistry.latestVersion() + ); + app = ExampleRegistryApp(address(ownerApp)); + } + + function testZeroInitialOwner() public virtual { + uint256 minTeleporterVersion = teleporterRegistry.latestVersion(); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0))); + ownerApp = new ExampleRegistryOwnableApp( + address(teleporterRegistry), address(0), minTeleporterVersion + ); + } +} + +contract TeleporterRegistryOwnableAppUpgradeableTest is BaseTeleporterRegistryOwnableAppTest { + function setUp() public virtual override { + BaseTeleporterRegistryOwnableAppTest.setUp(); + ExampleRegistryOwnableAppUpgradeable upgradeableApp = + new ExampleRegistryOwnableAppUpgradeable(); + upgradeableApp.initialize( + address(teleporterRegistry), DEFAULT_OWNER_ADDRESS, teleporterRegistry.latestVersion() + ); + ownerApp = ExampleRegistryOwnableApp(address(upgradeableApp)); + app = ExampleRegistryApp(address(ownerApp)); + } + + function testZeroInitialOwner() public { + ExampleRegistryOwnableAppUpgradeable upgradeableApp = + new ExampleRegistryOwnableAppUpgradeable(); + uint256 minTeleporterVersion = teleporterRegistry.latestVersion(); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0))); + upgradeableApp.initialize(address(teleporterRegistry), address(0), minTeleporterVersion); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryTests.t.sol new file mode 100644 index 000000000..5443ce438 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/TeleporterRegistryTests.t.sol @@ -0,0 +1,331 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {TeleporterRegistry, ProtocolRegistryEntry} from "../TeleporterRegistry.sol"; +import { + TeleporterMessenger, IWarpMessenger, WarpMessage +} from "@teleporter/TeleporterMessenger.sol"; + +contract TeleporterRegistryTest is Test { + bytes32 public constant MOCK_BLOCK_CHAIN_ID = bytes32(uint256(123456)); + address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; + + TeleporterRegistry public teleporterRegistry; + address public teleporterAddress; + + event AddProtocolVersion(uint256 indexed version, address indexed protocolAddress); + + event LatestVersionUpdated(uint256 indexed oldVersion, uint256 indexed newVersion); + + function setUp() public virtual { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(MOCK_BLOCK_CHAIN_ID) + ); + teleporterRegistry = new TeleporterRegistry(new ProtocolRegistryEntry[](0)); + assertEq(0, teleporterRegistry.latestVersion()); + + teleporterAddress = address(new TeleporterMessenger()); + } + + function testAddProtocolVersionBasic() public { + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + + _addProtocolVersion(teleporterRegistry, teleporterAddress); + assertEq(latestVersion + 1, teleporterRegistry.latestVersion()); + assertEq(teleporterAddress, address(teleporterRegistry.getLatestTeleporter())); + assertEq( + teleporterRegistry.getVersionFromAddress(teleporterAddress), + teleporterRegistry.latestVersion() + ); + + // Check that adding a protocol version with a version that is not the increment of the latest version succeeds + latestVersion = teleporterRegistry.latestVersion(); + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + 2, teleporterAddress, address(teleporterRegistry) + ); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq(latestVersion + 2, teleporterRegistry.latestVersion()); + assertEq(teleporterAddress, address(teleporterRegistry.getLatestTeleporter())); + } + + function testAddNonContractAddress() public { + // Check that adding a protocol version with a protocol address that is not a contract address succeeds + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + 2, address(this), address(teleporterRegistry) + ); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq(latestVersion + 2, teleporterRegistry.latestVersion()); + assertEq(address(this), teleporterRegistry.getAddressFromVersion(latestVersion + 2)); + } + + function testAddOldVersion() public { + // Check that adding a protocol version that has not been registered, but is less than the latest version succeeds + // First add to latest version by skipping a version. + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + 2, teleporterAddress, address(teleporterRegistry) + ); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq(latestVersion + 2, teleporterRegistry.latestVersion()); + assertEq(teleporterAddress, teleporterRegistry.getAddressFromVersion(latestVersion + 2)); + + // latestVersion + 1 was skipped in previous check, is not registered, and is less than latestVersion() + uint256 oldVersion = latestVersion + 1; + warpMessage = + _createWarpOffChainMessage(oldVersion, address(this), address(teleporterRegistry)); + + // Make sure that oldVersion is not registered, and is less than latestVersion() + assertEq(oldVersion, teleporterRegistry.latestVersion() - 1); + vm.expectRevert(_formatRegistryErrorMessage("version not found")); + teleporterRegistry.getAddressFromVersion(oldVersion); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq(address(this), teleporterRegistry.getAddressFromVersion(oldVersion)); + assertEq(oldVersion + 1, teleporterRegistry.latestVersion()); + } + + function testRepeatedProtocolAddressUsesGreaterVersion() public { + // Check that adding the same protocol address for two versions succeeds, + // and returns the greater version in getVersionFromAddress. + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + 2, teleporterAddress, address(teleporterRegistry) + ); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq(latestVersion + 2, teleporterRegistry.latestVersion()); + assertEq(teleporterAddress, teleporterRegistry.getAddressFromVersion(latestVersion + 2)); + + // latestVersion + 1 was skipped in previous check, is not registered, and is less than latestVersion() + uint256 oldVersion = latestVersion + 1; + warpMessage = + _createWarpOffChainMessage(oldVersion, teleporterAddress, address(teleporterRegistry)); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq(teleporterAddress, teleporterRegistry.getAddressFromVersion(oldVersion)); + + assertEq(latestVersion + 2, teleporterRegistry.getVersionFromAddress(teleporterAddress)); + } + + function testAddExistingVersion() public { + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + + // Add a new version to the registiry + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + 1, teleporterAddress, address(teleporterRegistry) + ); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq(latestVersion + 1, teleporterRegistry.latestVersion()); + assertEq(teleporterAddress, teleporterRegistry.getAddressFromVersion(latestVersion + 1)); + + // Check that adding a protocol version with the same version fails + vm.expectRevert(_formatRegistryErrorMessage("version already exists")); + teleporterRegistry.addProtocolVersion(messageIndex); + } + + function testAddZeroProtocolAddress() public { + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + + // Check that adding an invalid protocol address of address(0) fails + WarpMessage memory warpMessage = + _createWarpOffChainMessage(latestVersion + 1, address(0), address(teleporterRegistry)); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectRevert(_formatRegistryErrorMessage("zero protocol address")); + teleporterRegistry.addProtocolVersion(messageIndex); + } + + function testAddZeroVersion() public { + uint32 messageIndex = 0; + + // Check that adding an invalid version of 0 fails + WarpMessage memory warpMessage = + _createWarpOffChainMessage(0, teleporterAddress, address(teleporterRegistry)); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectRevert(_formatRegistryErrorMessage("zero version")); + teleporterRegistry.addProtocolVersion(messageIndex); + } + + function testGetAddressFromVersion() public { + _addProtocolVersion(teleporterRegistry, teleporterAddress); + uint256 latestVersion = teleporterRegistry.latestVersion(); + + // First test success case + assertEq(teleporterAddress, teleporterRegistry.getAddressFromVersion(latestVersion)); + + // Check that getting version 0 fails + vm.expectRevert(_formatRegistryErrorMessage("zero version")); + teleporterRegistry.getAddressFromVersion(0); + + // Check that getting a version that doesn't exist fails + vm.expectRevert(_formatRegistryErrorMessage("version not found")); + teleporterRegistry.getAddressFromVersion(latestVersion + 1); + } + + function testGetVersionFromAddress() public { + _addProtocolVersion(teleporterRegistry, teleporterAddress); + uint256 latestVersion = teleporterRegistry.latestVersion(); + + // First test success case + assertEq(latestVersion, teleporterRegistry.getVersionFromAddress(teleporterAddress)); + + // Check that getting a version of an address that doesn't exist reverts + vm.expectRevert(_formatRegistryErrorMessage("protocol address not found")); + teleporterRegistry.getVersionFromAddress(address(this)); + } + + function testInvalidWarpMessage() public { + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + 1, teleporterAddress, address(teleporterRegistry) + ); + + // Check if warp message is invalid from getVerifiedWarpMessage + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, false); + + vm.expectRevert(_formatRegistryErrorMessage("invalid warp message")); + teleporterRegistry.addProtocolVersion(messageIndex); + + // Check if we have an invalid source chain ID + warpMessage.sourceChainID = bytes32(uint256(1234567)); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectRevert(_formatRegistryErrorMessage("invalid source chain ID")); + teleporterRegistry.addProtocolVersion(messageIndex); + + // Check if we have an invalid origin sender address + warpMessage.sourceChainID = MOCK_BLOCK_CHAIN_ID; + warpMessage.originSenderAddress = address(this); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectRevert(_formatRegistryErrorMessage("invalid origin sender address")); + teleporterRegistry.addProtocolVersion(messageIndex); + + // Check if we have an invalid destination address + warpMessage = _createWarpOffChainMessage( + latestVersion + 1, teleporterAddress, address(teleporterRegistry) + ); + warpMessage.payload = abi.encode( + ProtocolRegistryEntry({version: latestVersion + 1, protocolAddress: teleporterAddress}), + address(this) + ); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectRevert(_formatRegistryErrorMessage("invalid destination address")); + teleporterRegistry.addProtocolVersion(messageIndex); + } + + function testMaxVersionIncrement() public { + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + + // Adding a version that matches the max version increment succeeds + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + teleporterRegistry.MAX_VERSION_INCREMENT(), + teleporterAddress, + address(teleporterRegistry) + ); + + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + teleporterRegistry.addProtocolVersion(messageIndex); + assertEq( + latestVersion + teleporterRegistry.MAX_VERSION_INCREMENT(), + teleporterRegistry.latestVersion() + ); + + latestVersion = teleporterRegistry.latestVersion(); + // Adding a version that is greater than the max version increment fails + warpMessage = _createWarpOffChainMessage( + latestVersion + teleporterRegistry.MAX_VERSION_INCREMENT() + 1, + teleporterAddress, + address(teleporterRegistry) + ); + + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectRevert(_formatRegistryErrorMessage("version increment too high")); + teleporterRegistry.addProtocolVersion(messageIndex); + } + + function _addProtocolVersion( + TeleporterRegistry registry, + address newProtocolAddress + ) internal { + uint256 latestVersion = registry.latestVersion(); + uint32 messageIndex = 0; + WarpMessage memory warpMessage = + _createWarpOffChainMessage(latestVersion + 1, newProtocolAddress, address(registry)); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectEmit(true, true, true, true, address(registry)); + emit AddProtocolVersion(latestVersion + 1, newProtocolAddress); + vm.expectEmit(true, true, true, true, address(registry)); + emit LatestVersionUpdated(latestVersion, latestVersion + 1); + registry.addProtocolVersion(messageIndex); + } + + function _mockGetVerifiedWarpMessage( + uint32 messageIndex, + WarpMessage memory warpMessage, + bool isValid + ) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (messageIndex)), + abi.encode(warpMessage, isValid) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (messageIndex)) + ); + } + + function _createWarpOffChainMessage( + uint256 version, + address protocolAddress, + address registryAddress + ) internal view returns (WarpMessage memory) { + return WarpMessage({ + sourceChainID: MOCK_BLOCK_CHAIN_ID, + originSenderAddress: TeleporterRegistry(registryAddress).VALIDATORS_SOURCE_ADDRESS(), + payload: abi.encode( + ProtocolRegistryEntry({version: version, protocolAddress: protocolAddress}), + registryAddress + ) + }); + } + + function _formatRegistryErrorMessage( + bytes memory errorMessage + ) internal pure returns (bytes memory) { + return abi.encodePacked("TeleporterRegistry: ", errorMessage); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/UnpauseTeleporterAddressTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/UnpauseTeleporterAddressTests.t.sol new file mode 100644 index 000000000..4e7a4d807 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/UnpauseTeleporterAddressTests.t.sol @@ -0,0 +1,121 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import {TeleporterMessenger} from "@teleporter/TeleporterMessenger.sol"; + +abstract contract UnpauseTeleporterAddressTest is BaseTeleporterRegistryAppTest { + function testUnpauseLessThanMinimumVersion() public { + // Check the case where a Teleporter address was previously paused, and now updates the minimum version. + // If the dApp unpauses the previous Teleporter address, it still can not receive messages from it, + // since receiving messages still checks against minimum Teleporter version. + + // Pause the Teleporter address + _pauseTeleporterAddressSuccess(app, teleporterAddress); + + // The Teleporter address paused no longer can deliver messages to the app + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Add a new Teleporter address to the registry and update minimum version + address newTeleporterAddress = address(new TeleporterMessenger()); + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + _updateMinTeleporterVersionSuccess(app, teleporterRegistry.latestVersion()); + + // Unpause the previously paused Teleporter address + _unpauseTeleporterAddressSuccess(app, teleporterAddress); + + // The previously paused Teleporter address still can not deliver messages to the app + // because the minimum version is still greater than the Teleporter address version + vm.expectRevert(_formatErrorMessage("invalid Teleporter sender")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Check that the new Teleporter address delivers messages fine + vm.prank(newTeleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testUnpauseTeleporterAddressBasic() public { + // Check that the teleporterAddress is not paused initially + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + // Check that teleporterAddress can not deliver messages once paused + _pauseTeleporterAddressSuccess(app, teleporterAddress); + vm.expectRevert(_formatErrorMessage("Teleporter address paused")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Unpause the teleporterAddress and check that it can deliver messages again + _unpauseTeleporterAddressSuccess(app, teleporterAddress); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testAlreadyUnpausedTeleporterAddress() public { + // Check unpausing for an address that was never paused + vm.expectRevert(_formatErrorMessage("address not paused")); + app.unpauseTeleporterAddress(teleporterAddress); + + // Pause the Teleporter address + _pauseTeleporterAddressSuccess(app, teleporterAddress); + + // Try to unpause the Teleporter address first time should succeed + _unpauseTeleporterAddressSuccess(app, teleporterAddress); + + // Try to unpause the Teleporter address second time should fail + vm.expectRevert(_formatErrorMessage("address not paused")); + app.unpauseTeleporterAddress(teleporterAddress); + } + + function testUnpauseBeforeRegister() public { + // Check that a Teleporter address can be paused before it is registered with the registry + + // Create a new Teleporter address that is not registered with the registry + address newTeleporterAddress = address(new TeleporterMessenger()); + + // Pause the new Teleporter address before it is registered + _pauseTeleporterAddressSuccess(app, newTeleporterAddress); + + // Unpause before the Teleporter address is registered + _unpauseTeleporterAddressSuccess(app, newTeleporterAddress); + + // Register the new Teleporter address + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + + // Check that the new Teleporter address is unpaused + vm.prank(newTeleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testUnpauseAfterRegister() public { + // Check that a Teleporter address can be paused before it is registered with the registry + + // Create a new Teleporter address that is not registered with the registry + address newTeleporterAddress = address(new TeleporterMessenger()); + + // Pause the new Teleporter address before it is registered + _pauseTeleporterAddressSuccess(app, newTeleporterAddress); + + // Register the new Teleporter address + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + + // Unpause before the Teleporter address is registered + _unpauseTeleporterAddressSuccess(app, newTeleporterAddress); + + // Check that the new Teleporter address is unpaused + vm.prank(newTeleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testUnpauseZeroAddress() public { + // Check that a zero address can not be paused + vm.expectRevert(_formatErrorMessage("zero Teleporter address")); + app.unpauseTeleporterAddress(address(0)); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/tests/UpdateMinTeleporterVersionTests.t.sol b/icm-contracts/contracts/teleporter/registry/tests/UpdateMinTeleporterVersionTests.t.sol new file mode 100644 index 000000000..fe83a40f2 --- /dev/null +++ b/icm-contracts/contracts/teleporter/registry/tests/UpdateMinTeleporterVersionTests.t.sol @@ -0,0 +1,108 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {BaseTeleporterRegistryAppTest} from "./BaseTeleporterRegistryAppTests.t.sol"; +import {TeleporterMessenger, WarpMessage} from "@teleporter/TeleporterMessenger.sol"; + +abstract contract UpdateMinTeleporterVersionTest is BaseTeleporterRegistryAppTest { + function testMessageDeliveryFromOutdatedVersion() public { + // First check that calling with initial teleporter address works + assertEq(app.getMinTeleporterVersion(), 1); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Now add new protocol version to registry and update the app's min version + address newTeleporterAddress = address(new TeleporterMessenger()); + _addProtocolVersion(teleporterRegistry, newTeleporterAddress); + + _updateMinTeleporterVersionSuccess(app, teleporterRegistry.latestVersion()); + assertEq(app.getMinTeleporterVersion(), 2); + + // Check that calling with the old teleporter address fails + vm.expectRevert(_formatErrorMessage("invalid Teleporter sender")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Check that calling with the new teleporter address works + vm.prank(newTeleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testUpdateToNonRegisteredVersion() public { + // The Teleporter registry allows skipping versions, so we don't have to update + // in increments of 1. This test checks that the app can update to a version + // that is not registered in the registry. + + // First add to the registry by skipping a version + address newTeleporterAddress = address(new TeleporterMessenger()); + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint32 messageIndex = 0; + WarpMessage memory warpMessage = _createWarpOffChainMessage( + latestVersion + 2, newTeleporterAddress, address(teleporterRegistry) + ); + _mockGetVerifiedWarpMessage(messageIndex, warpMessage, true); + + vm.expectEmit(true, true, true, true, address(teleporterRegistry)); + emit AddProtocolVersion(latestVersion + 2, newTeleporterAddress); + vm.expectEmit(true, true, true, true, address(teleporterRegistry)); + emit LatestVersionUpdated(latestVersion, latestVersion + 2); + teleporterRegistry.addProtocolVersion(messageIndex); + + // Check that the latest version is updated + assertEq(teleporterRegistry.latestVersion(), latestVersion + 2); + + // Make sure that a version was skipped and is not registered + uint256 skippedVersion = latestVersion + 1; + vm.expectRevert(_formatRegistryErrorMessage("version not found")); + teleporterRegistry.getTeleporterFromVersion(skippedVersion); + + // Update to the skipped version + _updateMinTeleporterVersionSuccess(app, skippedVersion); + assertEq(app.getMinTeleporterVersion(), skippedVersion); + + // Make sure that the old minimum Teleporter version can not deliver messages + vm.expectRevert(_formatErrorMessage("invalid Teleporter sender")); + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + + // Make sure that the new minimum Teleporter version can still deliver messages + vm.prank(newTeleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testUpdateWithCurrentVersion() public { + // Get the current minimum Teleporter version + uint256 minTeleporterVersion = app.getMinTeleporterVersion(); + + // Check that current latest version is equal to minimum version + assertEq(minTeleporterVersion, teleporterRegistry.latestVersion()); + + // Try to update to current minimum version, should fail + vm.expectRevert(_formatErrorMessage("not greater than current minimum version")); + app.updateMinTeleporterVersion(minTeleporterVersion); + + // Check that minimum version is still the same + assertEq(app.getMinTeleporterVersion(), minTeleporterVersion); + + // Check that calling with the teleporter address works + vm.prank(teleporterAddress); + app.receiveTeleporterMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_ORIGIN_ADDRESS, ""); + } + + function testUpdateWithGreaterThanLatestVersion() public { + // Get current latest version and minimum Teleporter version + uint256 latestVersion = teleporterRegistry.latestVersion(); + uint256 minTeleporterVersion = app.getMinTeleporterVersion(); + + // Try to update to a version greater than the latest version, should fail + vm.expectRevert(_formatErrorMessage("invalid Teleporter version")); + app.updateMinTeleporterVersion(latestVersion + 1); + + // Check that minimum version is still the same + assertEq(app.getMinTeleporterVersion(), minTeleporterVersion); + } +} diff --git a/icm-contracts/contracts/teleporter/registry/upgrade-uml.png b/icm-contracts/contracts/teleporter/registry/upgrade-uml.png new file mode 100644 index 000000000..086cf205b Binary files /dev/null and b/icm-contracts/contracts/teleporter/registry/upgrade-uml.png differ diff --git a/icm-contracts/contracts/teleporter/tests/AddFeeAmountTests.t.sol b/icm-contracts/contracts/teleporter/tests/AddFeeAmountTests.t.sol new file mode 100644 index 000000000..ebaf5ec83 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/AddFeeAmountTests.t.sol @@ -0,0 +1,154 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterFeeInfo, + TeleporterMessageReceipt, + IERC20 +} from "./TeleporterMessengerTest.t.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; + +contract AddFeeAmountTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSuccess() public { + // First submit a message with a small fee + uint256 originalFeeAmount = 10; + bytes32 messageID = + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, originalFeeAmount); + + // Add to the fee + uint256 additionalFeeAmount = 131313; + uint256 totalFeeAmount = originalFeeAmount + additionalFeeAmount; + vm.expectCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transferFrom, + (address(this), address(teleporterMessenger), additionalFeeAmount) + ) + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit AddFeeAmount( + messageID, + TeleporterFeeInfo({feeTokenAddress: address(_mockFeeAsset), amount: totalFeeAmount}) + ); + teleporterMessenger.addFeeAmount(messageID, address(_mockFeeAsset), additionalFeeAmount); + + // Get the fee info to make sure it is properly updated. + (address actualFeeAsset, uint256 actualFeeAmount) = + teleporterMessenger.getFeeInfo(messageID); + assertEq(actualFeeAsset, address(_mockFeeAsset)); + assertEq(actualFeeAmount, totalFeeAmount); + } + + function testInvalidMessage() public { + // Add to the fee amount of a message that doesn't exist. Expect revert. + uint256 additionalFeeAmount = 131313; + bytes32 fakeMessageID = bytes32(uint256(13)); + vm.expectRevert(_formatTeleporterErrorMessage("message not found")); + teleporterMessenger.addFeeAmount(fakeMessageID, address(_mockFeeAsset), additionalFeeAmount); + } + + function testMessageAlreadyDelivered() public { + // First submit a message with a small fee + uint256 originalFeeAmount = 10; + uint256 expectedNonce = _getNextMessageNonce(); + bytes32 messageID = + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, originalFeeAmount); + + // Now mock receiving a message back from that L1 with a receipt of the above message. + address relayerRewardAddress = 0xA66884fAdC0D4d7B7eedcF61Eb863Ff413bB6234; + TeleporterMessageReceipt[] memory receipts = new TeleporterMessageReceipt[](1); + receipts[0] = TeleporterMessageReceipt({ + receivedMessageNonce: expectedNonce, + relayerRewardAddress: relayerRewardAddress + }); + + _receiveTestMessage(DEFAULT_DESTINATION_BLOCKCHAIN_ID, 1, relayerRewardAddress, receipts); + + // Now try to add to the fee of the message. Should revert since the message receipt was received already. + uint256 additionalFeeAmount = 131313; + vm.expectRevert(_formatTeleporterErrorMessage("message not found")); + teleporterMessenger.addFeeAmount(messageID, address(_mockFeeAsset), additionalFeeAmount); + } + + function testInvalidAmount() public { + // First submit a message with a small fee + uint256 originalFeeAmount = 10; + bytes32 messageID = + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, originalFeeAmount); + + // Expect revert when adding 0 additional amount. + uint256 additionalFeeAmount = 0; + vm.expectRevert(_formatTeleporterErrorMessage("zero additional fee amount")); + teleporterMessenger.addFeeAmount(messageID, address(_mockFeeAsset), additionalFeeAmount); + } + + function testMismatchFeeAsset() public { + // First submit a message with a small fee + uint256 originalFeeAmount = 10; + bytes32 messageID = + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, originalFeeAmount); + + // Expect revert when using a different fee asset than originally used. + uint256 additionalFeeAmount = 131313; + address differentFeeAsset = 0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664; + vm.expectRevert(_formatTeleporterErrorMessage("invalid fee asset contract address")); + teleporterMessenger.addFeeAmount(messageID, differentFeeAsset, additionalFeeAmount); + } + + function testInvalidFeeAsset() public { + // First submit a message with a small fee + uint256 originalFeeAmount = 10; + bytes32 messageID = + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, originalFeeAmount); + + // Expect revert when using an invalid fee asset. + uint256 additionalFeeAmount = 131313; + address invalidFeeAsset = address(0); + vm.expectRevert(_formatTeleporterErrorMessage("zero fee asset contract address")); + teleporterMessenger.addFeeAmount(messageID, invalidFeeAsset, additionalFeeAmount); + } + + function testInsufficientBalance() public { + // First submit a message with a small fee + uint256 originalFeeAmount = 10; + bytes32 messageID = + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, originalFeeAmount); + + // Add to the fee, but mock the ERC20 contract returning an error from transferFrom + uint256 additionalFeeAmount = 131313; + vm.expectCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transferFrom, + (address(this), address(teleporterMessenger), additionalFeeAmount) + ) + ); + vm.mockCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transferFrom, + (address(this), address(teleporterMessenger), additionalFeeAmount) + ), + abi.encode(false) + ); + vm.expectRevert( + abi.encodeWithSelector( + SafeERC20.SafeERC20FailedOperation.selector, address(_mockFeeAsset) + ) + ); + + teleporterMessenger.addFeeAmount(messageID, address(_mockFeeAsset), additionalFeeAmount); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/CheckAllowedRelayerTests.t.sol b/icm-contracts/contracts/teleporter/tests/CheckAllowedRelayerTests.t.sol new file mode 100644 index 000000000..d465e09c7 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/CheckAllowedRelayerTests.t.sol @@ -0,0 +1,42 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterMessenger} from "../TeleporterMessenger.sol"; +import {Test} from "@forge-std/Test.sol"; + +contract CheckIsAllowedRelayerTest is TeleporterMessenger, Test { + function testIsSpecifiedAllowedRelayer() public pure { + address relayerAddress = 0x6288dAdf62B57dd9A4ddcd02F88A98d0eb6c2598; + address[] memory allowedRelayers = new address[](3); + allowedRelayers[0] = relayerAddress; + allowedRelayers[1] = 0xDeaDBeEf62B57DD9a4ddcD02F88a98d0eb6C2598; + allowedRelayers[2] = 0xfFfFfFFffFB57Dd9A4ddcD02f88A98D0Eb6c2598; + assertTrue(_checkIsAllowedRelayer(relayerAddress, allowedRelayers)); + } + + function testAnyRelayerIsAllowed() public pure { + address[] memory relayerAddresses = new address[](3); + relayerAddresses[0] = 0x6288dAdf62B57dd9A4ddcd02F88A98d0eb6c2598; + relayerAddresses[1] = 0xDeaDBeEf62B57DD9a4ddcD02F88a98d0eb6C2598; + relayerAddresses[2] = 0xfFfFfFFffFB57Dd9A4ddcD02f88A98D0Eb6c2598; + address[] memory allowedRelayers = new address[](0); + + for (uint256 i; i < relayerAddresses.length; ++i) { + assertTrue(_checkIsAllowedRelayer(relayerAddresses[i], allowedRelayers)); + } + } + + function testUnauthorizedRelayer() public pure { + address relayerAddress = 0x6288dAdf62B57dd9A4ddcd02F88A98d0eb6c2598; + address[] memory allowedRelayers = new address[](3); + allowedRelayers[0] = 0xCaFEbabE62B57DD9A4dDcD02F88A98d0Eb6c2598; + allowedRelayers[1] = 0xDeaDBeEf62B57DD9a4ddcD02F88a98d0eb6C2598; + allowedRelayers[2] = 0xfFfFfFFffFB57Dd9A4ddcD02f88A98D0Eb6c2598; + + assertFalse(_checkIsAllowedRelayer(relayerAddress, allowedRelayers)); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/FallbackReceiveTests.t.sol b/icm-contracts/contracts/teleporter/tests/FallbackReceiveTests.t.sol new file mode 100644 index 000000000..0f93da31e --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/FallbackReceiveTests.t.sol @@ -0,0 +1,159 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + WarpMessage, + TeleporterMessageReceipt +} from "./TeleporterMessengerTest.t.sol"; + +enum FallbackReceiveAction { + Fail, + Succeed +} + +contract FallbackReceiveApp { + bytes32 public immutable sourceBlockchainID; + address public immutable originSenderAddress; + uint256 public nonce; + + constructor(bytes32 sourceBlockchainID_, address originSenderAddress_) { + sourceBlockchainID = sourceBlockchainID_; + originSenderAddress = originSenderAddress_; + } + + // solhint-disable-next-line no-complex-fallback, payable-fallback + fallback( + bytes calldata data + ) external returns (bytes memory) { + bytes4 selector = bytes4(data[:4]); + // Check that the function selector was for receiveTeleporterMessage. + require( + selector == bytes4(keccak256("receiveTeleporterMessage(bytes32,address,bytes)")), + "FallbackReceiveApp: Invalid selector" + ); + + (bytes32 sourceBlockchainID_, address originSenderAddress_, bytes memory message) = + abi.decode(data[4:], (bytes32, address, bytes)); + + require( + sourceBlockchainID == sourceBlockchainID_, "FallbackReceiveApp: Invalid origin chain ID" + ); + require( + originSenderAddress == originSenderAddress_, + "FallbackReceiveApp: Invalid origin sender address" + ); + + FallbackReceiveAction action = abi.decode(message, (FallbackReceiveAction)); + + if (action == FallbackReceiveAction.Fail) { + revert("FallbackReceiveApp: Fallback failed"); + } else if (action == FallbackReceiveAction.Succeed) { + nonce++; + } else { + revert("FallbackReceiveApp: Invalid action"); + } + + return abi.encode(nonce); + } +} + +contract FallbackReceiveTest is TeleporterMessengerTest { + FallbackReceiveApp public destinationContract; + + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + destinationContract = new FallbackReceiveApp(DEFAULT_SOURCE_BLOCKCHAIN_ID, address(this)); + } + + function testFallbackSuccess() public { + uint256 nonce = destinationContract.nonce(); + + // Construct the mock message to be received. + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: _getNextMessageNonce(), + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: abi.encode(FallbackReceiveAction.Succeed) + }); + bytes32 receivedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message and check that message execution was successful. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + receivedMessageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecuted(receivedMessageID, DEFAULT_SOURCE_BLOCKCHAIN_ID); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check that the nonce was incremented. + assertEq(destinationContract.nonce(), nonce + 1); + } + + function testFallbackFail() public { + uint256 nonce = destinationContract.nonce(); + + // Construct the mock message to be received. + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: _getNextMessageNonce(), + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: abi.encode(FallbackReceiveAction.Fail) + }); + bytes32 receivedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message and check that message execution failed. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + receivedMessageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecutionFailed( + receivedMessageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive + ); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check that the nonce was not changed. + assertEq(destinationContract.nonce(), nonce); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/GetFeeInfoTests.t.sol b/icm-contracts/contracts/teleporter/tests/GetFeeInfoTests.t.sol new file mode 100644 index 000000000..7cf4d3786 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/GetFeeInfoTests.t.sol @@ -0,0 +1,77 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterMessengerTest, TeleporterMessageReceipt} from "./TeleporterMessengerTest.t.sol"; + +contract GetFeeInfoTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSuccess() public { + // First submit a message with a fee + uint256 feeAmount = 1687435413; + bytes32 messageID = _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, feeAmount); + + // Get the fee info to make sure it is correct. + (address actualFeeAsset, uint256 actualFeeAmount) = + teleporterMessenger.getFeeInfo(messageID); + assertEq(actualFeeAsset, address(_mockFeeAsset)); + assertEq(actualFeeAmount, feeAmount); + } + + function testFeeOnTransferTokenUsed() public { + // First submit a message with a fee, but mock their being a "fee on token transfer" + // during the call to transferFrom. + uint256 feeAmount = 1687435413; + uint256 tokenTransferFee = 35413; + _mockFeeAsset.setFeeOnTransferSender(address(this), tokenTransferFee); + bytes32 messageID = _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, feeAmount); + + // Get the fee info to make sure it is correct, including the fee amount being less than + // the amount specified when submitting the message due to the "fee on token transfer". + (address actualFeeAsset, uint256 actualFeeAmount) = + teleporterMessenger.getFeeInfo(messageID); + assertEq(actualFeeAsset, address(_mockFeeAsset)); + assertEq(actualFeeAmount, feeAmount - tokenTransferFee); + } + + function testAfterReceipt() public { + // First submit a message with a small fee + uint256 feeAmount = 10; + uint256 expectedNonce = _getNextMessageNonce(); + bytes32 messageID = _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, feeAmount); + + // Now mock receiving a message back from that L1 with a receipt of the above message. + address relayerRewardAddress = 0xA66884fAdC0D4d7B7eedcF61Eb863Ff413bB6234; + TeleporterMessageReceipt[] memory receipts = new TeleporterMessageReceipt[](1); + receipts[0] = TeleporterMessageReceipt({ + receivedMessageNonce: expectedNonce, + relayerRewardAddress: relayerRewardAddress + }); + _receiveTestMessage(DEFAULT_DESTINATION_BLOCKCHAIN_ID, 6, relayerRewardAddress, receipts); + + // Now, if we get the fee info for the message it should be reported as zero since the receipt has already been received. + (address actualFeeAsset, uint256 actualFeeAmount) = + teleporterMessenger.getFeeInfo(messageID); + assertEq(actualFeeAsset, address(0)); + assertEq(actualFeeAmount, 0); + } + + function testInvalidMessage() public view { + bytes32 fakeMessageID = bytes32(uint256(4646)); + + // Get the fee info to make sure it is zero since the message doesn't exist. + (address actualFeeAsset, uint256 actualFeeAmount) = + teleporterMessenger.getFeeInfo(fakeMessageID); + assertEq(actualFeeAsset, address(0)); + assertEq(actualFeeAmount, 0); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/GetMessageHashTests.t.sol b/icm-contracts/contracts/teleporter/tests/GetMessageHashTests.t.sol new file mode 100644 index 000000000..defb5b55d --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/GetMessageHashTests.t.sol @@ -0,0 +1,65 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageReceipt +} from "./TeleporterMessengerTest.t.sol"; + +contract GetMessageHashTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSuccess() public { + // Submit a message + TeleporterMessage memory expectedMessage = TeleporterMessage({ + messageNonce: _getNextMessageNonce(), + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: new bytes(0) + }); + bytes32 messageID = _sendTestMessageWithNoFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID); + + bytes memory expectedMessageBytes = abi.encode(expectedMessage); + bytes32 expectedMessageHash = keccak256(expectedMessageBytes); + + // Get its stored hash + bytes32 actualMessageHash = teleporterMessenger.getMessageHash(messageID); + assertEq(actualMessageHash, expectedMessageHash); + } + + function testMessageAlreadyReceived() public { + // Submit a message + uint256 expectedNonce = _getNextMessageNonce(); + bytes32 messageID = _sendTestMessageWithNoFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID); + + // Now mock receiving a message back from that L1 with a receipt of the above message. + address relayerRewardAddress = 0xA66884fAdC0D4d7B7eedcF61Eb863Ff413bB6234; + TeleporterMessageReceipt[] memory receipts = new TeleporterMessageReceipt[](1); + receipts[0] = TeleporterMessageReceipt({ + receivedMessageNonce: expectedNonce, + relayerRewardAddress: relayerRewardAddress + }); + _receiveTestMessage(DEFAULT_DESTINATION_BLOCKCHAIN_ID, 43, relayerRewardAddress, receipts); + + // Now the message hash should be cleared. + assertEq(teleporterMessenger.getMessageHash(messageID), bytes32(0)); + } + + function testMessageDoesNotExist() public view { + assertEq(teleporterMessenger.getMessageHash(bytes32(uint256(42))), bytes32(0)); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/GetNextMessageIdTests.t.sol b/icm-contracts/contracts/teleporter/tests/GetNextMessageIdTests.t.sol new file mode 100644 index 000000000..6f1ce75ef --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/GetNextMessageIdTests.t.sol @@ -0,0 +1,69 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessageInput, + TeleporterFeeInfo, + IWarpMessenger +} from "./TeleporterMessengerTest.t.sol"; + +contract GetNextMessageIDTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testGetMessageID() public { + // Generate the next expected message ID manually. + bytes32 expectedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + _getNextMessageNonce() + ); + + // Check the contract reports the same as expected. + assertEq( + teleporterMessenger.getNextMessageID(DEFAULT_DESTINATION_BLOCKCHAIN_ID), + expectedMessageID + ); + + // Send a message to ensure it is assigned the expected ID. + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(bytes32(0)) + ); + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(0), + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(0), amount: uint256(0)}), + requiredGasLimit: 1e6, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + bytes32 messageID = teleporterMessenger.sendCrossChainMessage(messageInput); + assertEq(messageID, expectedMessageID); + + // Generate the next expected message ID now that a message has been sent. + bytes32 secondExpectedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + _getNextMessageNonce() + ); + + // Check the contract reports the same as expected, and that is different than the first ID. + assertEq( + teleporterMessenger.getNextMessageID(DEFAULT_DESTINATION_BLOCKCHAIN_ID), + secondExpectedMessageID + ); + assertNotEq(expectedMessageID, secondExpectedMessageID); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/GetOutstandingReceiptsToSendTests.t.sol b/icm-contracts/contracts/teleporter/tests/GetOutstandingReceiptsToSendTests.t.sol new file mode 100644 index 000000000..5d6b2b4cc --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/GetOutstandingReceiptsToSendTests.t.sol @@ -0,0 +1,234 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageInput, + TeleporterFeeInfo, + TeleporterMessageReceipt, + IWarpMessenger +} from "./TeleporterMessengerTest.t.sol"; + +contract GetOutstandingReceiptsToSendTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + // getOutstandingReceipts to send is private to the teleporter contract, but we can test + // its correctness by looking at the receipts included in messages that are submitted to be + // sent. First, mock receiving 3 messages such that we have 3 outstanding receipts. Then, send + // a message that should contain the receipts. Finally, send another message that should not + // have any more receipts since they were included in the previous message. + function testSuccess() public { + bytes32 blockchainID = + bytes32(hex"11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff"); + + // Assemble mock receipt information that we will expect to be + // included in a subsequent message sent to another chain. + TeleporterMessageReceipt[] memory expectedReceipts = new TeleporterMessageReceipt[](3); + expectedReceipts[0] = + TeleporterMessageReceipt(13, 0xF1DFE63909C027Ed814Dd92C5a3644590abf4850); + expectedReceipts[1] = + TeleporterMessageReceipt(42, 0xF1DFE63909C027Ed814Dd92C5a3644590abf4850); + expectedReceipts[2] = + TeleporterMessageReceipt(94, 0xdc00AB1cF6942cE0891eF1AC5ff686833Fa0C542); + + // Mock receiving each of the messages corresponding to the receipts. + for (uint256 i; i < expectedReceipts.length; ++i) { + _receiveTestMessage( + blockchainID, + expectedReceipts[i].receivedMessageNonce, + expectedReceipts[i].relayerRewardAddress, + new TeleporterMessageReceipt[](0) + ); + } + + // Now that we have "received" 3 mock messages, when we send a message back to the + // other chain, we should expect to see the 3 receipts included in the message metadata. + TeleporterMessage memory expectedMessage = + _createMockTeleporterMessage(_getNextMessageNonce(), hex"deadbeef"); + expectedMessage.receipts = expectedReceipts; + expectedMessage.destinationBlockchainID = blockchainID; + bytes32 expectedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + expectedMessage.destinationBlockchainID, + expectedMessage.messageNonce + ); + TeleporterFeeInfo memory feeInfo = TeleporterFeeInfo(address(0), 0); + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: expectedMessage.destinationBlockchainID, + destinationAddress: expectedMessage.destinationAddress, + feeInfo: feeInfo, + requiredGasLimit: expectedMessage.requiredGasLimit, + allowedRelayerAddresses: expectedMessage.allowedRelayerAddresses, + message: expectedMessage.message + }); + + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(expectedMessageID) + ); + + // Expect the exact message to be passed to the precompile. + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.sendWarpMessage, (abi.encode(expectedMessage))) + ); + + // Expect the SendCrossChainMessage event to be emitted. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + expectedMessageID, messageInput.destinationBlockchainID, expectedMessage, feeInfo + ); + + // Submit the message. + teleporterMessenger.sendCrossChainMessage(messageInput); + + // Submit another message to be sent to check that it does not contain any more receipts. + TeleporterMessage memory nextExpectedMessage = + _createMockTeleporterMessage(_getNextMessageNonce(), hex"deadbeef"); + nextExpectedMessage.destinationBlockchainID = blockchainID; + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.sendWarpMessage, (abi.encode(nextExpectedMessage))) + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + nextExpectedMessage.destinationBlockchainID, + nextExpectedMessage.messageNonce + ), + messageInput.destinationBlockchainID, + nextExpectedMessage, + feeInfo + ); + + // Submit the new message. + teleporterMessenger.sendCrossChainMessage(messageInput); + } + + // Test that when there are more than the maximum limit of receipts to include in a message (5), + // the first batch of receipts on the first outbound message has the maximum batch size, and + // next contains the remaining receipts. + function testExceedsLimit() public { + bytes32 blockchainID = + bytes32(hex"11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff"); + + // Assemble mock receipt information that we will expect to be + // included in a subsequent message sent to another chain. + TeleporterMessageReceipt[] memory expectedReceiptsBatch1 = new TeleporterMessageReceipt[](5); // the limit of receipts per message is 5. + expectedReceiptsBatch1[0] = + TeleporterMessageReceipt(13, 0xF1DFE63909C027Ed814Dd92C5a3644590abf4850); + expectedReceiptsBatch1[1] = + TeleporterMessageReceipt(42, 0x52A258ED593C793251a89bfd36caE158EE9fC4F8); + expectedReceiptsBatch1[2] = + TeleporterMessageReceipt(94, 0xdc00AB1cF6942cE0891eF1AC5ff686833Fa0C542); + expectedReceiptsBatch1[3] = + TeleporterMessageReceipt(3, 0xdc00AB1cF6942cE0891eF1AC5ff686833Fa0C542); + expectedReceiptsBatch1[4] = + TeleporterMessageReceipt(53, 0xdc00AB1cF6942cE0891eF1AC5ff686833Fa0C542); + + TeleporterMessageReceipt[] memory expectedReceiptsBatch2 = new TeleporterMessageReceipt[](2); // the limit of receipts per message is 5. + expectedReceiptsBatch2[0] = + TeleporterMessageReceipt(75, 0xdc00AB1cF6942cE0891eF1AC5ff686833Fa0C542); + expectedReceiptsBatch2[1] = + TeleporterMessageReceipt(80, 0xdc00AB1cF6942cE0891eF1AC5ff686833Fa0C542); + + // Mock receiving each of the messages corresponding to the receipts. + for (uint256 i; i < expectedReceiptsBatch1.length; ++i) { + _receiveTestMessage( + blockchainID, + expectedReceiptsBatch1[i].receivedMessageNonce, + expectedReceiptsBatch1[i].relayerRewardAddress, + new TeleporterMessageReceipt[](0) + ); + } + for (uint256 i; i < expectedReceiptsBatch2.length; ++i) { + _receiveTestMessage( + blockchainID, + expectedReceiptsBatch2[i].receivedMessageNonce, + expectedReceiptsBatch2[i].relayerRewardAddress, + new TeleporterMessageReceipt[](0) + ); + } + + // Now that we have "received" 7 mock messages, when we send a message back to the + // other chain, we should expect to see the 5 receipts included in the message metadata because + // that is the max receipt batch size limit. + TeleporterMessage memory expectedMessage = + _createMockTeleporterMessage(_getNextMessageNonce(), hex"deadbeef"); + expectedMessage.receipts = expectedReceiptsBatch1; + expectedMessage.destinationBlockchainID = blockchainID; + TeleporterFeeInfo memory feeInfo = TeleporterFeeInfo(address(0), 0); + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: expectedMessage.destinationBlockchainID, + destinationAddress: expectedMessage.destinationAddress, + feeInfo: feeInfo, + requiredGasLimit: expectedMessage.requiredGasLimit, + allowedRelayerAddresses: expectedMessage.allowedRelayerAddresses, + message: expectedMessage.message + }); + + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(bytes32(0)) + ); + + // Expect the exact message to be passed to the precompile. + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.sendWarpMessage, (abi.encode(expectedMessage))) + ); + + // Expect the SendCrossChainMessage event to be emitted. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + expectedMessage.destinationBlockchainID, + expectedMessage.messageNonce + ), + messageInput.destinationBlockchainID, + expectedMessage, + feeInfo + ); + + // Submit the message. + teleporterMessenger.sendCrossChainMessage(messageInput); + + // Submit another message to be sent to check that it contains the remaining 2 receipts to be sent. + TeleporterMessage memory nextExpectedMessage = + _createMockTeleporterMessage(_getNextMessageNonce(), hex"deadbeef"); + nextExpectedMessage.receipts = expectedReceiptsBatch2; + nextExpectedMessage.destinationBlockchainID = blockchainID; + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.sendWarpMessage, (abi.encode(nextExpectedMessage))) + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + nextExpectedMessage.destinationBlockchainID, + nextExpectedMessage.messageNonce + ), + messageInput.destinationBlockchainID, + nextExpectedMessage, + feeInfo + ); + + // Submit the new message. + teleporterMessenger.sendCrossChainMessage(messageInput); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/GetRelayerRewardAddressTests.t.sol b/icm-contracts/contracts/teleporter/tests/GetRelayerRewardAddressTests.t.sol new file mode 100644 index 000000000..04f14ff80 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/GetRelayerRewardAddressTests.t.sol @@ -0,0 +1,58 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterMessengerTest, TeleporterMessageReceipt} from "./TeleporterMessengerTest.t.sol"; + +contract GetRelayerRewardAddressTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSuccess() public { + // Receive a message + uint256 mockNonce = 8; + bytes32 mockMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, mockNonce + ); + address relayerRewardAddress = 0xCAFebAbeDc0D4D7B7EEdCf61eb863fF413BB6234; + _receiveTestMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + mockNonce, + relayerRewardAddress, + new TeleporterMessageReceipt[](0) + ); + + // Now it has the relayer reward address. + assertEq(teleporterMessenger.getRelayerRewardAddress(mockMessageID), relayerRewardAddress); + } + + function testZeroRelayerRewardAddress() public { + // Receive a message with a zero relayer reward address + uint256 mockNonce = 4343; + bytes32 mockMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, mockNonce + ); + _receiveTestMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, mockNonce, address(0), new TeleporterMessageReceipt[](0) + ); + + // Check that the zero address is returned as the reward address. + assertEq(teleporterMessenger.getRelayerRewardAddress(mockMessageID), address(0)); + } + + function testMessageNotReceived() public { + // Before receiving the given message, getRelayerRewardAddress should revert. + bytes32 mockMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 4242 + ); + vm.expectRevert(_formatTeleporterErrorMessage("message not received")); + teleporterMessenger.getRelayerRewardAddress(mockMessageID); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/HandleInitialMessageExecutionTests.t.sol b/icm-contracts/contracts/teleporter/tests/HandleInitialMessageExecutionTests.t.sol new file mode 100644 index 000000000..1e98c3dbe --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/HandleInitialMessageExecutionTests.t.sol @@ -0,0 +1,264 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageReceipt, + WarpMessage +} from "./TeleporterMessengerTest.t.sol"; +import {ITeleporterMessenger} from "../ITeleporterMessenger.sol"; +import {ITeleporterReceiver} from "../ITeleporterReceiver.sol"; + +enum SampleMessageReceiverAction { + Receive, + ReceiveRecursive +} + +contract SampleMessageReceiver is ITeleporterReceiver { + address public immutable teleporterContract; + string public latestMessage; + bytes32 public latestMessageSenderSubnetID; + address public latestMessageSenderAddress; + + constructor( + address teleporterContractAddress + ) { + teleporterContract = teleporterContractAddress; + } + + function receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes calldata message + ) external { + require(msg.sender == teleporterContract, "unauthorized"); + // Decode the payload to recover the action and corresponding function parameters + (SampleMessageReceiverAction action, bytes memory actionData) = + abi.decode(message, (SampleMessageReceiverAction, bytes)); + if (action == SampleMessageReceiverAction.Receive) { + (string memory messageString, bool succeed) = abi.decode(actionData, (string, bool)); + _receiveMessage(sourceBlockchainID, originSenderAddress, messageString, succeed); + } else if (action == SampleMessageReceiverAction.ReceiveRecursive) { + string memory messageString = abi.decode(actionData, (string)); + _receiveMessageRecursive(sourceBlockchainID, originSenderAddress, messageString); + } else { + revert("invalid action"); + } + } + + // Stores the message in this contract to be fetched by anyone. + function _receiveMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + string memory message, + bool succeed + ) internal { + require(msg.sender == teleporterContract, "unauthorized"); + require(succeed, "intended to fail"); + latestMessage = message; + latestMessageSenderSubnetID = sourceBlockchainID; + latestMessageSenderAddress = originSenderAddress; + } + + // Tries to recursively call the teleporterContract to receive a message, which should always fail. + function _receiveMessageRecursive( + bytes32 sourceBlockchainID, + address originSenderAddress, + string memory message + ) internal { + require(msg.sender == teleporterContract, "unauthorized"); + ITeleporterMessenger messenger = ITeleporterMessenger(teleporterContract); + messenger.receiveCrossChainMessage(0, address(42)); + latestMessage = message; + latestMessageSenderSubnetID = sourceBlockchainID; + latestMessageSenderAddress = originSenderAddress; + } +} + +contract HandleInitialMessageExecutionTest is TeleporterMessengerTest { + SampleMessageReceiver public destinationContract; + + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + destinationContract = new SampleMessageReceiver(address(teleporterMessenger)); + } + + function testSuccess() public { + // Construct the mock message to be received. + string memory messageString = "Testing successful message"; + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 42, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: abi.encode(SampleMessageReceiverAction.Receive, abi.encode(messageString, true)) + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message and check that message execution was successful. + bytes32 expectedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + expectedMessageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecuted(expectedMessageID, DEFAULT_SOURCE_BLOCKCHAIN_ID); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check that the message had the proper affect on the destination contract. + assertEq(destinationContract.latestMessage(), messageString); + assertEq(destinationContract.latestMessageSenderSubnetID(), DEFAULT_SOURCE_BLOCKCHAIN_ID); + assertEq(destinationContract.latestMessageSenderAddress(), address(this)); + assertEq( + teleporterMessenger.getRelayerRewardAddress(expectedMessageID), + DEFAULT_RELAYER_REWARD_ADDRESS + ); + } + + function testInsufficientGasProvided() public { + // Construct the mock message to be received. + string memory messageString = "Testing successful message"; + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 42, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: uint256( + bytes32(hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") // UINT256_MAX + ), + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: abi.encode(SampleMessageReceiverAction.Receive, abi.encode(messageString, true)) + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message. + vm.expectRevert(_formatTeleporterErrorMessage("insufficient gas")); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + } + + function testCannotReceiveMessageRecursively() public { + // Construct the mock message to be received. + string memory messageString = "Testing successful message"; + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 42, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: abi.encode(SampleMessageReceiverAction.ReceiveRecursive, abi.encode(messageString)) + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + bytes32 messageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message - this does not revert because the recursive call + // is considered a failed message execution, but the message itself is + // still successfully delivered. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + messageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecutionFailed(messageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check that the message hash was stored in state and the message did not have any affect on the destination. + assertEq(destinationContract.latestMessage(), ""); + assertEq(destinationContract.latestMessageSenderSubnetID(), bytes32(0)); + assertEq(destinationContract.latestMessageSenderAddress(), address(0)); + assertEq( + teleporterMessenger.getRelayerRewardAddress(messageID), DEFAULT_RELAYER_REWARD_ADDRESS + ); + vm.expectRevert(_formatTeleporterErrorMessage("retry execution failed")); + teleporterMessenger.retryMessageExecution(DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + } + + function testStoreHashOfFailedMessageExecution() public { + // Construct the mock message to be received. + string memory messageString = "Testing successful message"; + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 42, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: abi.encode(SampleMessageReceiverAction.Receive, abi.encode(messageString, false)) + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + bytes32 messageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + messageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecutionFailed(messageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check that the message hash was stored in state and the message did not have any affect on the destination. + assertEq(destinationContract.latestMessage(), ""); + assertEq(destinationContract.latestMessageSenderSubnetID(), bytes32(0)); + assertEq(destinationContract.latestMessageSenderAddress(), address(0)); + assertEq( + teleporterMessenger.getRelayerRewardAddress(messageID), DEFAULT_RELAYER_REWARD_ADDRESS + ); + vm.expectRevert(_formatTeleporterErrorMessage("retry execution failed")); + teleporterMessenger.retryMessageExecution(DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/InitializeBlockchainIDTests.t.sol b/icm-contracts/contracts/teleporter/tests/InitializeBlockchainIDTests.t.sol new file mode 100644 index 000000000..40db2974d --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/InitializeBlockchainIDTests.t.sol @@ -0,0 +1,117 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import { + TeleporterMessenger, + TeleporterMessage, + TeleporterMessageInput, + TeleporterMessageReceipt, + TeleporterFeeInfo, + IWarpMessenger, + WarpMessage +} from "../TeleporterMessenger.sol"; + +// TeleporterMessengerTest and its child contracts all initialize the blockchain ID in the set up +// step for ease of use. This test contract is separate to allow for testing the initialization +// step itself. +contract InitializeBlockchainIDTest is Test { + address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; + bytes32 public constant DEFAULT_SOURCE_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + bytes32 public constant DEFAULT_DESTINATION_BLOCKCHAIN_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + + TeleporterMessenger public teleporterMessenger; + + // Set up the Teleporter contract but leave the blockchain ID uninitialized. + function setUp() public virtual { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(DEFAULT_DESTINATION_BLOCKCHAIN_ID) + ); + + teleporterMessenger = new TeleporterMessenger(); + } + + function testUninitialized() public { + assertEq(teleporterMessenger.blockchainID(), bytes32(0)); + vm.expectRevert("TeleporterMessenger: zero blockchain ID"); + teleporterMessenger.getNextMessageID(DEFAULT_DESTINATION_BLOCKCHAIN_ID); + } + + function testSuccess() public { + bytes32 res = teleporterMessenger.initializeBlockchainID(); + assertEq(res, DEFAULT_DESTINATION_BLOCKCHAIN_ID); + assertEq(teleporterMessenger.blockchainID(), DEFAULT_DESTINATION_BLOCKCHAIN_ID); + + // Should be able to call multiple times and get same result. + res = teleporterMessenger.initializeBlockchainID(); + assertEq(res, DEFAULT_DESTINATION_BLOCKCHAIN_ID); + } + + function testInitializedBySending() public { + // Send a message. + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(bytes32(0)) + ); + teleporterMessenger.sendCrossChainMessage( + TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(1), + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(0), amount: 0}), + requiredGasLimit: 1000, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }) + ); + + // Check the blockchain ID is initialized. + assertEq(teleporterMessenger.blockchainID(), DEFAULT_DESTINATION_BLOCKCHAIN_ID); + } + + function testInitializedByReceiving() public { + TeleporterMessage memory teleporterMessage = TeleporterMessage({ + messageNonce: 1, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(1), + requiredGasLimit: 100, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: new bytes(0) + }); + WarpMessage memory warpMessage = WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(teleporterMessenger), + payload: abi.encode(teleporterMessage) + }); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (0)), + abi.encode(warpMessage, true) + ); + teleporterMessenger.receiveCrossChainMessage(0, address(0)); + + // Check the blockchain ID is initialized. + assertEq(teleporterMessenger.blockchainID(), DEFAULT_DESTINATION_BLOCKCHAIN_ID); + } + + function testCannotInitializeToZero() public { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(bytes32(0)) + ); + + vm.expectRevert("TeleporterMessenger: zero blockchain ID"); + teleporterMessenger.initializeBlockchainID(); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/MarkReceiptTests.t.sol b/icm-contracts/contracts/teleporter/tests/MarkReceiptTests.t.sol new file mode 100644 index 000000000..635e74237 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/MarkReceiptTests.t.sol @@ -0,0 +1,200 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessageReceipt, + TeleporterMessage, + TeleporterFeeInfo, + WarpMessage +} from "./TeleporterMessengerTest.t.sol"; + +contract MarkReceiptTest is TeleporterMessengerTest { + struct FeeRewardInfo { + uint256 feeAmount; + address relayerRewardAddress; + } + + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + // This test first mocks sending 3 messages (each with fees) to a different L1. + // It then mocks receiving a message back from that L1 with the receipt information + // for each of the 3 messages sent, and checks that the relayers can redeem their rewards. + function testCheckRelayersUponReceipt() public { + // Submit a few mock messages to be sent. + FeeRewardInfo[3] memory feeRewardInfos = [ + FeeRewardInfo(1111111111111111, 0x52A258ED593C793251a89bfd36caE158EE9fC4F8), + FeeRewardInfo(2222222222222222, 0xeF6ed43EB8Ff15E336D64d1468947cA1046824E6), + FeeRewardInfo(3333333333333333, 0xdc00AB1cF6942cE0891eF1AC5ff686833Fa0C542) + ]; + + uint256[3] memory messageNonces; + bytes32[3] memory messageIDs; + for (uint256 i; i < feeRewardInfos.length; ++i) { + messageNonces[i] = _getNextMessageNonce(); + messageIDs[i] = + _sendTestMessageWithFee(DEFAULT_SOURCE_BLOCKCHAIN_ID, feeRewardInfos[i].feeAmount); + } + + // Mock receiving a message with the 3 receipts from the mock messages sent above. + TeleporterMessageReceipt[] memory receipts = + new TeleporterMessageReceipt[](feeRewardInfos.length); + for (uint256 i; i < receipts.length; ++i) { + receipts[i] = TeleporterMessageReceipt({ + receivedMessageNonce: messageNonces[i], + relayerRewardAddress: feeRewardInfos[i].relayerRewardAddress + }); + } + uint256 receivedMessageNonce = 1; + TeleporterMessage memory messageToReceive = + _createMockTeleporterMessage(receivedMessageNonce, new bytes(0)); + messageToReceive.receipts = receipts; + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the mock message. + address expectedRelayerRewardAddress = 0x93753a9eA4C9D6eeed9f64eA92E97ce1f5FBAeDe; + + for (uint256 i; i < feeRewardInfos.length; ++i) { + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiptReceived( + messageIDs[i], + DEFAULT_SOURCE_BLOCKCHAIN_ID, + feeRewardInfos[i].relayerRewardAddress, + TeleporterFeeInfo({ + feeTokenAddress: address(_mockFeeAsset), + amount: feeRewardInfos[i].feeAmount + }) + ); + } + teleporterMessenger.receiveCrossChainMessage(0, expectedRelayerRewardAddress); + + // Check that the relayers have redeemable balances + for (uint256 i; i < feeRewardInfos.length; ++i) { + assertEq( + teleporterMessenger.checkRelayerRewardAmount( + feeRewardInfos[i].relayerRewardAddress, address(_mockFeeAsset) + ), + feeRewardInfos[i].feeAmount + ); + } + + // Check that the message received is considered delivered, and that the relayer reward address is stored. + bytes32 expectedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, receivedMessageNonce + ); + assertEq( + teleporterMessenger.getRelayerRewardAddress(expectedMessageID), + expectedRelayerRewardAddress + ); + assertTrue(teleporterMessenger.messageReceived(expectedMessageID)); + + // Check that the message hashes for the message receipts we received have been cleared. + for (uint256 i; i < receipts.length; ++i) { + assertEq(teleporterMessenger.getMessageHash(messageIDs[i]), bytes32(0)); + } + } + + function testReceiptForNoFeeMessage() public { + // Submit a a mock message with no fee. + uint256 sentMessageNonce = _getNextMessageNonce(); + bytes32 sentMessageID = _sendTestMessageWithNoFee(DEFAULT_SOURCE_BLOCKCHAIN_ID); + + // Mock receiving a message with the a receipts of the mock message sent above. + TeleporterMessageReceipt[] memory receipts = new TeleporterMessageReceipt[](1); + receipts[0] = TeleporterMessageReceipt({ + receivedMessageNonce: sentMessageNonce, + relayerRewardAddress: DEFAULT_RELAYER_REWARD_ADDRESS + }); + uint256 receivedMessageNonce = 42; + bytes32 receivedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, receivedMessageNonce + ); + TeleporterMessage memory messageToReceive = + _createMockTeleporterMessage(receivedMessageNonce, new bytes(0)); + messageToReceive.receipts = receipts; + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the mock message. + address expectedRelayerRewardAddress = 0x2F20537C2F5c57231866DE9D0CE33d0681a200D4; + + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiptReceived( + sentMessageID, + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_RELAYER_REWARD_ADDRESS, + TeleporterFeeInfo({feeTokenAddress: address(0), amount: 0}) + ); + teleporterMessenger.receiveCrossChainMessage(0, expectedRelayerRewardAddress); + + // Check that the message received is considered delivered, and that the relayer reward address is stored. + assertEq( + teleporterMessenger.getRelayerRewardAddress(receivedMessageID), + expectedRelayerRewardAddress + ); + assertTrue(teleporterMessenger.messageReceived(receivedMessageID)); + } + + function testDuplicateReceiptAllowed() public { + // Submit a mock message to be sent. + FeeRewardInfo memory feeRewardInfo = + FeeRewardInfo(1111111111111111, 0x52A258ED593C793251a89bfd36caE158EE9fC4F8); + uint256 sentMessageNonce = _getNextMessageNonce(); + _sendTestMessageWithFee(DEFAULT_SOURCE_BLOCKCHAIN_ID, feeRewardInfo.feeAmount); + + // Mock receiving a message with the 2 receipts for the same mock message above. + TeleporterMessageReceipt[] memory receipts = new TeleporterMessageReceipt[](2); + TeleporterMessageReceipt memory receipt = TeleporterMessageReceipt({ + receivedMessageNonce: sentMessageNonce, + relayerRewardAddress: feeRewardInfo.relayerRewardAddress + }); + receipts[0] = receipt; + receipts[1] = receipt; + uint256 receivedMessageNonce = 12; + bytes32 receivedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, receivedMessageNonce + ); + TeleporterMessage memory messageToReceive = + _createMockTeleporterMessage(receivedMessageNonce, new bytes(0)); + messageToReceive.receipts = receipts; + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the mock message. + address expectedRelayerRewardAddress = 0x6DAEF0D63ea44C801b655Fd97fe3804B9bFCC097; + teleporterMessenger.receiveCrossChainMessage(0, expectedRelayerRewardAddress); + + // Check that the relayer redeemable balances was only added once. + assertEq( + teleporterMessenger.checkRelayerRewardAmount( + feeRewardInfo.relayerRewardAddress, address(_mockFeeAsset) + ), + feeRewardInfo.feeAmount + ); + + // Check that the message received is considered delivered, and that the relayer reward address is stored. + assertEq( + teleporterMessenger.getRelayerRewardAddress(receivedMessageID), + expectedRelayerRewardAddress + ); + assertTrue(teleporterMessenger.messageReceived(receivedMessageID)); + + // Check that the message hashes for the message receipts we received have been cleared. + assertEq(teleporterMessenger.getMessageHash(receivedMessageID), bytes32(0)); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/MessageReceivedTests.t.sol b/icm-contracts/contracts/teleporter/tests/MessageReceivedTests.t.sol new file mode 100644 index 000000000..9eb159f8f --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/MessageReceivedTests.t.sol @@ -0,0 +1,45 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterMessengerTest, TeleporterMessageReceipt} from "./TeleporterMessengerTest.t.sol"; + +contract MessageReceivedTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testReceivedMessage() public { + // Mock receiving a message from another L1. + address relayerRewardAddress = 0xA66884fAdC0D4d7B7eedcF61Eb863Ff413bB6234; + uint256 messageNonce = 1; + bytes32 messageID = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, messageNonce + ); + _receiveTestMessage( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageNonce, + relayerRewardAddress, + new TeleporterMessageReceipt[](0) + ); + + assertEq(teleporterMessenger.messageReceived(messageID), true); + } + + function testUnreceivedMessage() public view { + assertEq( + teleporterMessenger.messageReceived( + teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 1 + ) + ), + false + ); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/ReceiptsQueueTests.t.sol b/icm-contracts/contracts/teleporter/tests/ReceiptsQueueTests.t.sol new file mode 100644 index 000000000..6250496da --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/ReceiptsQueueTests.t.sol @@ -0,0 +1,124 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ReceiptQueue} from "../ReceiptQueue.sol"; +import {TeleporterMessageReceipt} from "../ITeleporterMessenger.sol"; + +/// forge-config: default.allow_internal_expect_revert = true +contract ReceiptQueueTest is Test { + using ReceiptQueue for ReceiptQueue.TeleporterMessageReceiptQueue; + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + + ReceiptQueue.TeleporterMessageReceiptQueue private _queue; + + // Add 3 elements to the queue. + TeleporterMessageReceipt private _receipt1 = TeleporterMessageReceipt({ + receivedMessageNonce: 543, + relayerRewardAddress: 0x10eB43ef5982628728E3E4bb9F78834f67Fbb40b + }); + TeleporterMessageReceipt private _receipt2 = TeleporterMessageReceipt({ + receivedMessageNonce: 684384, + relayerRewardAddress: 0x10eB43ef5982628728E3E4bb9F78834f67Fbb40b + }); + TeleporterMessageReceipt private _receipt3 = TeleporterMessageReceipt({ + receivedMessageNonce: 654351, + relayerRewardAddress: 0xcC8E718045817AebA89592C72Ae1C9917f5D0894 + }); + + function testEnqueueDequeueSuccess() public { + // Check the initial size is zero. + assertEq(_queue.size(), 0); + + _queue.enqueue(_receipt1); + _queue.enqueue(_receipt2); + _queue.enqueue(_receipt3); + + // Check the size is now three. + assertEq(_queue.size(), 3); + + // Dequeue 3 elements and check they are given in the correct order (FIFO). + TeleporterMessageReceipt memory result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, _receipt1.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt1.relayerRewardAddress); + result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, _receipt2.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt2.relayerRewardAddress); + result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, _receipt3.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt3.relayerRewardAddress); + + // Check the size is now 0 again. + assertEq(_queue.size(), 0); + + // Enqueue two more of the same item to check you can have duplicates, followed by the second and third. + _queue.enqueue(_receipt1); + _queue.enqueue(_receipt1); + _queue.enqueue(_receipt2); + _queue.enqueue(_receipt3); + + // Check the size again. + assertEq(_queue.size(), 4); + + // Finally dequeue the elements and once again check they are returned in the correct order. + result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, _receipt1.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt1.relayerRewardAddress); + result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, _receipt1.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt1.relayerRewardAddress); + result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, _receipt2.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt2.relayerRewardAddress); + result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, _receipt3.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt3.relayerRewardAddress); + } + + function testDequeueRevertIfEmptyQueue() public { + // Check that you can't dequeue from empty queue. + vm.expectRevert(_formatReceiptQueueErrorMessage("empty queue")); + TeleporterMessageReceipt memory result = _queue.dequeue(); + assertEq(result.receivedMessageNonce, 0); + assertEq(result.relayerRewardAddress, address(0)); + } + + function testGetReceiptAtIndex() public { + _queue.enqueue(_receipt1); + _queue.enqueue(_receipt1); + _queue.enqueue(_receipt2); + _queue.enqueue(_receipt3); + + // Check the size again. + assertEq(_queue.size(), 4); + + // Check that you can get receipts at specific indexes. + TeleporterMessageReceipt memory result = _queue.getReceiptAtIndex(2); + assertEq(result.receivedMessageNonce, _receipt2.receivedMessageNonce); + assertEq(result.relayerRewardAddress, _receipt2.relayerRewardAddress); + + // Check can't get an out of index element. + vm.expectRevert(_formatReceiptQueueErrorMessage("index out of bounds")); + result = _queue.getReceiptAtIndex(4); + } + + function testGetReceiptAtIndexWithEmptyQueue() public { + // Check that you can't get receipts from empty queue. + vm.expectRevert(_formatReceiptQueueErrorMessage("index out of bounds")); + TeleporterMessageReceipt memory result = _queue.getReceiptAtIndex(0); + assertEq(result.receivedMessageNonce, 0); + assertEq(result.relayerRewardAddress, address(0)); + } + + function _formatReceiptQueueErrorMessage( + bytes memory errorMessage + ) private pure returns (bytes memory) { + return abi.encodePacked("ReceiptQueue: ", errorMessage); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/ReceiveCrossChainMessageTests.t.sol b/icm-contracts/contracts/teleporter/tests/ReceiveCrossChainMessageTests.t.sol new file mode 100644 index 000000000..c67c8129f --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/ReceiveCrossChainMessageTests.t.sol @@ -0,0 +1,271 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageReceipt, + WarpMessage, + IWarpMessenger +} from "./TeleporterMessengerTest.t.sol"; + +// Tests of the logic in receiveCrossChainMessage. +// Tests of the execution and receipts helper methods are split out into independent +// test files in HandleInitialMessageExecutionTests and MarkReceiptAndPayRelayerTests. +contract ReceiveCrossChainMessagedTest is TeleporterMessengerTest { + bytes public constant DEFAULT_MESSAGE_PAYLOAD = + hex"cafebabe11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff11223344556677889900aabbccddeeffdeadbeef"; + + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSuccess() public { + // This test contract must be an allowed relayer since it is what + // will call receiveCrossChainMessage. + address[] memory allowedRelayers = new address[](2); + allowedRelayers[0] = address(this); + allowedRelayers[1] = DEFAULT_RELAYER_REWARD_ADDRESS; + + // Construct the test message to be received. + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 987, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: allowedRelayers, + receipts: new TeleporterMessageReceipt[](0), + message: DEFAULT_MESSAGE_PAYLOAD + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + bytes32 messageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Check receipt queue size + assertEq(teleporterMessenger.getReceiptQueueSize(DEFAULT_SOURCE_BLOCKCHAIN_ID), 0); + + // Receive the message. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + messageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check receipt queue size + assertEq(teleporterMessenger.getReceiptQueueSize(DEFAULT_SOURCE_BLOCKCHAIN_ID), 1); + + // Check receipt queue contents + TeleporterMessageReceipt memory receipt = + teleporterMessenger.getReceiptAtIndex(DEFAULT_SOURCE_BLOCKCHAIN_ID, 0); + assertEq(receipt.receivedMessageNonce, messageToReceive.messageNonce); + assertEq(receipt.relayerRewardAddress, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Receive at a different index + messageToReceive.messageNonce = 654; + messageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + _setUpSuccessGetVerifiedWarpMessageMock(3, warpMessage); + + // Receive the message. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + messageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + teleporterMessenger.receiveCrossChainMessage(3, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check receipt queue size + assertEq(teleporterMessenger.getReceiptQueueSize(DEFAULT_SOURCE_BLOCKCHAIN_ID), 2); + + // Check receipt queue contents + receipt = teleporterMessenger.getReceiptAtIndex(DEFAULT_SOURCE_BLOCKCHAIN_ID, 1); + assertEq(receipt.receivedMessageNonce, messageToReceive.messageNonce); + assertEq(receipt.relayerRewardAddress, DEFAULT_RELAYER_REWARD_ADDRESS); + } + + function testNoValidMessage() public { + // Mock the call to the warp precompile to get the message failing. + WarpMessage memory emptyMessage = _createDefaultWarpMessage(bytes32(0), new bytes(0)); + + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (0)), + abi.encode(emptyMessage, false) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (0)) + ); + + vm.expectRevert(_formatTeleporterErrorMessage("invalid warp message")); + teleporterMessenger.receiveCrossChainMessage(0, address(1)); + + // Receive invalid message at index 3 + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (3)), + abi.encode(emptyMessage, false) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (3)) + ); + + vm.expectRevert(_formatTeleporterErrorMessage("invalid warp message")); + teleporterMessenger.receiveCrossChainMessage(3, address(1)); + } + + function testInvalidOriginSenderAddress() public { + // Construct the test message to be received. + TeleporterMessage memory messageToReceive = _createMockTeleporterMessage(1, new bytes(0)); + + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + address invalidSenderAddress = 0xb73aD7e0FF026a805D1f1186EAB89E41bf01835D; + warpMessage.originSenderAddress = invalidSenderAddress; + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + vm.expectRevert(_formatTeleporterErrorMessage("invalid origin sender address")); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + } + + function testInvalidDestinationBlockchainID() public { + // Construct the test message to be received. + TeleporterMessage memory messageToReceive = _createMockTeleporterMessage(1, new bytes(0)); + bytes32 invalidDestinationBlockchainID = + bytes32(hex"deadbeefcafebabedeadbeefcafebabedeadbeefcafebabedeadbeefcafebabe"); + messageToReceive.destinationBlockchainID = invalidDestinationBlockchainID; + + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + vm.expectRevert(_formatTeleporterErrorMessage("invalid destination chain ID")); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + } + + function testZeroMessageNonce() public { + // Construct the test message to be received. + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 0, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: DEFAULT_MESSAGE_PAYLOAD + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message. + vm.expectRevert(_formatTeleporterErrorMessage("zero message nonce")); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + } + + function testReceiveSameNonceFromMultipleChains() public { + bytes32 sourceBlockchainID1 = + bytes32(hex"1111111111111111111111111111111111111111111111111111111111111111"); + bytes32 sourceBlockchainID2 = + bytes32(hex"2222222222222222222222222222222222222222222222222222222222222222"); + uint256 mockMessageNonce = 5454; + bytes32 expectedMessageID1 = teleporterMessenger.calculateMessageID( + sourceBlockchainID1, DEFAULT_DESTINATION_BLOCKCHAIN_ID, mockMessageNonce + ); + bytes32 expectedMessageID2 = teleporterMessenger.calculateMessageID( + sourceBlockchainID2, DEFAULT_DESTINATION_BLOCKCHAIN_ID, mockMessageNonce + ); + + // Receive two messages with the same nonce from different source chains. + _receiveTestMessage( + sourceBlockchainID1, mockMessageNonce, address(0), new TeleporterMessageReceipt[](0) + ); + _receiveTestMessage( + sourceBlockchainID2, mockMessageNonce, address(0), new TeleporterMessageReceipt[](0) + ); + + // Check that both messages were received. + assertTrue(teleporterMessenger.messageReceived(expectedMessageID1)); + assertTrue(teleporterMessenger.messageReceived(expectedMessageID2)); + } + + function testMessageAlreadyReceived() public { + // Receive a message successfully. + testSuccess(); + + // Check you can't deliver it again. + vm.expectRevert(_formatTeleporterErrorMessage("message already received")); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + } + + function testUnauthorizedRelayer() public { + // It doesn't matter if the reward address is an allowed relayer. + // It is based on who calls receiveCrossChainMessage. + address[] memory allowedRelayers = new address[](1); + allowedRelayers[0] = DEFAULT_RELAYER_REWARD_ADDRESS; + + // Construct the test message to be received. + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 42, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: allowedRelayers, + receipts: new TeleporterMessageReceipt[](0), + message: DEFAULT_MESSAGE_PAYLOAD + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message. + vm.expectRevert(_formatTeleporterErrorMessage("unauthorized relayer")); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + } + + function testZeroRelayerAddress() public { + _receiveTestMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, 12, address(0), new TeleporterMessageReceipt[](0) + ); + } + + function testMessageSentToEOADoesNotExecute() public { + _receiveMessageSentToEOA(); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/RedeemRelayerRewardsTests.t.sol b/icm-contracts/contracts/teleporter/tests/RedeemRelayerRewardsTests.t.sol new file mode 100644 index 000000000..9e2b064b5 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/RedeemRelayerRewardsTests.t.sol @@ -0,0 +1,158 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageReceipt, + WarpMessage +} from "./TeleporterMessengerTest.t.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; + +contract RedeemRelayerRewardsTest is TeleporterMessengerTest { + struct FeeRewardInfo { + uint256 feeAmount; + address relayerRewardAddress; + } + + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testZeroRewardBalance() public { + vm.expectRevert(_formatTeleporterErrorMessage("no reward to redeem")); + teleporterMessenger.redeemRelayerRewards(address(_mockFeeAsset)); + } + + function testRedemptionFails() public { + FeeRewardInfo memory feeRewardInfo = + FeeRewardInfo(2222222222222222, 0xeF6ed43EB8Ff15E336D64d1468947cA1046824E6); + _setUpRelayerRewards(feeRewardInfo); + + vm.mockCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transfer, (feeRewardInfo.relayerRewardAddress, feeRewardInfo.feeAmount) + ), + abi.encode(false) + ); + vm.expectCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transfer, (feeRewardInfo.relayerRewardAddress, feeRewardInfo.feeAmount) + ) + ); + vm.prank(feeRewardInfo.relayerRewardAddress); + vm.expectRevert( + abi.encodeWithSelector( + SafeERC20.SafeERC20FailedOperation.selector, address(_mockFeeAsset) + ) + ); + teleporterMessenger.redeemRelayerRewards(address(_mockFeeAsset)); + + // Check that the relayer still has redeemable balance since the transfer failed. + assertEq( + teleporterMessenger.checkRelayerRewardAmount( + feeRewardInfo.relayerRewardAddress, address(_mockFeeAsset) + ), + feeRewardInfo.feeAmount + ); + } + + function testRedemptionSucceeds() public { + FeeRewardInfo memory feeRewardInfo = + FeeRewardInfo(2222222222222222, 0xeF6ed43EB8Ff15E336D64d1468947cA1046824E6); + _setUpRelayerRewards(feeRewardInfo); + + vm.mockCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transfer, (feeRewardInfo.relayerRewardAddress, feeRewardInfo.feeAmount) + ), + abi.encode(true) + ); + vm.expectCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transfer, (feeRewardInfo.relayerRewardAddress, feeRewardInfo.feeAmount) + ) + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit RelayerRewardsRedeemed( + feeRewardInfo.relayerRewardAddress, address(_mockFeeAsset), feeRewardInfo.feeAmount + ); + vm.prank(feeRewardInfo.relayerRewardAddress); + teleporterMessenger.redeemRelayerRewards(address(_mockFeeAsset)); + + // Check that the relayer redeemable balance is now 0. + assertEq( + teleporterMessenger.checkRelayerRewardAmount( + feeRewardInfo.relayerRewardAddress, address(_mockFeeAsset) + ), + 0 + ); + } + + // Mocks sending a message with the given fee info to another L1, and then + // receiving back a message with receipt of that message such that the relayer + // is able to redeem the reward. + function _setUpRelayerRewards( + FeeRewardInfo memory feeRewardInfo + ) private { + uint256 messageNonce = _getNextMessageNonce(); + _sendTestMessageWithFee(DEFAULT_SOURCE_BLOCKCHAIN_ID, feeRewardInfo.feeAmount); + + TeleporterMessageReceipt[] memory receipts = new TeleporterMessageReceipt[](1); + receipts[0] = TeleporterMessageReceipt({ + receivedMessageNonce: messageNonce, + relayerRewardAddress: feeRewardInfo.relayerRewardAddress + }); + TeleporterMessage memory messageToReceive = _createMockTeleporterMessage(1, new bytes(0)); + bytes32 receivedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + + messageToReceive.receipts = receipts; + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the mock message. + address expectedRelayerRewardAddress = 0x93753a9eA4C9D6eeed9f64eA92E97ce1f5FBAeDe; + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + receivedMessageID, + warpMessage.sourceChainID, + address(this), + expectedRelayerRewardAddress, + messageToReceive + ); + teleporterMessenger.receiveCrossChainMessage(0, expectedRelayerRewardAddress); + + // Check that the relayer has redeemable balance + assertEq( + teleporterMessenger.checkRelayerRewardAmount( + feeRewardInfo.relayerRewardAddress, address(_mockFeeAsset) + ), + feeRewardInfo.feeAmount + ); + + // Check that the message received is considered delivered, and that the relayer reward address is stored. + assertEq( + teleporterMessenger.getRelayerRewardAddress(receivedMessageID), + expectedRelayerRewardAddress + ); + assertTrue(teleporterMessenger.messageReceived(receivedMessageID)); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/RetryMessageExecutionTests.t.sol b/icm-contracts/contracts/teleporter/tests/RetryMessageExecutionTests.t.sol new file mode 100644 index 000000000..802bc254e --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/RetryMessageExecutionTests.t.sol @@ -0,0 +1,264 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageReceipt, + WarpMessage +} from "./TeleporterMessengerTest.t.sol"; +import {ITeleporterMessenger} from "../ITeleporterMessenger.sol"; +import {ITeleporterReceiver} from "../ITeleporterReceiver.sol"; + +enum FlakyMessageReceiverAction { + ReceiveMessage, + RetryReceive +} + +// A mock contract for testing retrying message execution. +// Any message delivered in block with an even timestamp will +// revert. Message delivered in block with an odd timestamp will succeed. +contract FlakyMessageReceiver is ITeleporterReceiver { + address public immutable teleporterContract; + string public latestMessage; + bytes32 public latestMessageSenderSubnetID; + address public latestMessageSenderAddress; + + constructor( + address teleporterContractAddress + ) { + teleporterContract = teleporterContractAddress; + } + + function receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes calldata messageBytes + ) external { + require(msg.sender == teleporterContract, "unauthorized"); + // Decode the payload to recover the action and corresponding function parameters + (FlakyMessageReceiverAction action, bytes memory actionData) = + abi.decode(messageBytes, (FlakyMessageReceiverAction, bytes)); + if (action == FlakyMessageReceiverAction.ReceiveMessage) { + string memory message = abi.decode(actionData, (string)); + _receiveMessage(sourceBlockchainID, originSenderAddress, message); + } else if (action == FlakyMessageReceiverAction.RetryReceive) { + string memory message = abi.decode(actionData, (string)); + _retryReceive(sourceBlockchainID, originSenderAddress, message); + } else { + revert("invalid action"); + } + } + + // Stores the message in this contract to be fetched by anyone. + function _receiveMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + string memory message + ) internal { + require(msg.sender == teleporterContract, "unauthorized"); + require(block.number % 2 != 0, "even block number"); + latestMessage = message; + latestMessageSenderSubnetID = sourceBlockchainID; + latestMessageSenderAddress = originSenderAddress; + } + + // Tries to call the teleporterContract to receive a message, which should always fail. + function _retryReceive( + bytes32 sourceBlockchainID, + address originSenderAddress, + string memory message + ) internal { + require(msg.sender == teleporterContract, "unauthorized"); + require(block.number % 2 != 0, "even block number"); + + ITeleporterMessenger messenger = ITeleporterMessenger(teleporterContract); + messenger.receiveCrossChainMessage(0, address(42)); + latestMessage = message; + latestMessageSenderSubnetID = sourceBlockchainID; + latestMessageSenderAddress = originSenderAddress; + } +} + +contract RetryMessageExecutionTest is TeleporterMessengerTest { + FlakyMessageReceiver public destinationContract; + + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + destinationContract = new FlakyMessageReceiver(address(teleporterMessenger)); + } + + function testSuccess() public { + _successfullyRetryMessage(); + } + + function testExecutionFailsAgain() public { + // First submit a message whose execution fails. + (bytes32 sourceBlockchainID, TeleporterMessage memory message,) = + _receiveFailedMessage(false); + + // Now retry it in another block with an even timestamp so that it fails again. + vm.expectRevert(_formatTeleporterErrorMessage("retry execution failed")); + teleporterMessenger.retryMessageExecution(sourceBlockchainID, message); + } + + function testMessageHashNotFound() public { + // Retrying a message that never was delivered should always fail. + TeleporterMessage memory fakeMessage = TeleporterMessage({ + messageNonce: 12345, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: new bytes(0) + }); + + vm.expectRevert(_formatTeleporterErrorMessage("message not found")); + teleporterMessenger.retryMessageExecution(DEFAULT_SOURCE_BLOCKCHAIN_ID, fakeMessage); + } + + function testInvalidMessageHash() public { + // First submit a message whose execution fails. + (bytes32 sourceBlockchainID, TeleporterMessage memory message,) = + _receiveFailedMessage(false); + + // Alter the message before retrying it. + message.message = "altered message"; + vm.expectRevert(_formatTeleporterErrorMessage("invalid message hash")); + teleporterMessenger.retryMessageExecution(sourceBlockchainID, message); + } + + function testCanNotRetryAgainAfterSuccess() public { + // Successfully retry a message execution. + (bytes32 sourceBlockchainID, TeleporterMessage memory message) = _successfullyRetryMessage(); + + // Now try again and make sure it's been cleared from state + vm.expectRevert(_formatTeleporterErrorMessage("message not found")); + teleporterMessenger.retryMessageExecution(sourceBlockchainID, message); + } + + function testCanNotReceiveMessageWhileRetrying() public { + // First submit a message whose execution fails. + (bytes32 sourceBlockchainID, TeleporterMessage memory message,) = + _receiveFailedMessage(false); + + // Now retry it within a block with an odd timestamp. + // It should still fail because it tries to re-enter the teleporter contract. + vm.expectRevert(); + teleporterMessenger.retryMessageExecution(sourceBlockchainID, message); + } + + function testEOAFailsThenRetrySucceeds() public { + (bytes32 sourceBlockchainID, address destinationAddress, TeleporterMessage memory message) = + _receiveMessageSentToEOA(); + + // Now mock a contract being deployed to the destination address. It will still return no + // data from the method being called, but code (with non-zero length) exists at the address. + vm.etch(destinationAddress, new bytes(10)); + + // Retrying the message execution should not revert. + teleporterMessenger.retryMessageExecution(sourceBlockchainID, message); + } + + function testEOAFailsAgainOnRetry() public { + (bytes32 sourceBlockchainID,, TeleporterMessage memory message) = _receiveMessageSentToEOA(); + + // Retrying the message execution should revert since there is still no contract deployed + // to the destination address. + vm.expectRevert(_formatTeleporterErrorMessage("destination address has no code")); + teleporterMessenger.retryMessageExecution(sourceBlockchainID, message); + } + + function _receiveFailedMessage( + bool retryReceive + ) internal returns (bytes32, TeleporterMessage memory, string memory) { + // Construct the mock message to be received. + string memory messageString = "Testing successful message"; + FlakyMessageReceiverAction action; + if (retryReceive) { + action = FlakyMessageReceiverAction.RetryReceive; + } else { + action = FlakyMessageReceiverAction.ReceiveMessage; + } + TeleporterMessage memory messageToReceive = TeleporterMessage({ + messageNonce: 42, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(destinationContract), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: abi.encode(action, abi.encode(messageString)) + }); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + bytes32 messageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + messageToReceive.messageNonce + ); + + // Mock the call to the warp precompile to get the message. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message in a block with an even height. + // The message should be successfully received, but its execution should fail. + vm.roll(12); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + messageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecutionFailed(messageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + // Check that the message execution didn't have any effect, but + // the message was marked as marked as delivered. + assertEq(destinationContract.latestMessage(), ""); + assertEq(destinationContract.latestMessageSenderSubnetID(), bytes32(0)); + assertEq(destinationContract.latestMessageSenderAddress(), address(0)); + assertEq( + teleporterMessenger.getRelayerRewardAddress(messageID), DEFAULT_RELAYER_REWARD_ADDRESS + ); + assertTrue(teleporterMessenger.messageReceived(messageID)); + + return (DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive, messageString); + } + + function _successfullyRetryMessage() internal returns (bytes32, TeleporterMessage memory) { + // First submit a message whose execution fails. + (bytes32 sourceBlockchainID, TeleporterMessage memory message, string memory messageString) + = _receiveFailedMessage(false); + + // Now retry the message execution in a block with an odd height, which should succeed. + vm.roll(13); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecuted( + teleporterMessenger.calculateMessageID( + sourceBlockchainID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, message.messageNonce + ), + sourceBlockchainID + ); + teleporterMessenger.retryMessageExecution(sourceBlockchainID, message); + + // Check that the message had the proper affect on the destination contract. + assertEq(destinationContract.latestMessage(), messageString); + assertEq(destinationContract.latestMessageSenderSubnetID(), sourceBlockchainID); + assertEq(destinationContract.latestMessageSenderAddress(), address(this)); + + return (sourceBlockchainID, message); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/RetrySendCrossChainMessageTests.t.sol b/icm-contracts/contracts/teleporter/tests/RetrySendCrossChainMessageTests.t.sol new file mode 100644 index 000000000..644fbc9cb --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/RetrySendCrossChainMessageTests.t.sol @@ -0,0 +1,75 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageReceipt +} from "./TeleporterMessengerTest.t.sol"; + +contract RetrySendCrossChainMessageTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSuccess() public { + // Send a message + uint256 expectedNonce = _getNextMessageNonce(); + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, 654456); + TeleporterMessage memory expectedMessage = TeleporterMessage({ + messageNonce: expectedNonce, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: new bytes(0) + }); + + // Retry it + teleporterMessenger.retrySendCrossChainMessage(expectedMessage); + } + + function testMessageNotFound() public { + TeleporterMessage memory fakeMessage = TeleporterMessage({ + messageNonce: 345, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: new bytes(0) + }); + vm.expectRevert(_formatTeleporterErrorMessage("message not found")); + teleporterMessenger.retrySendCrossChainMessage(fakeMessage); + } + + function testInvalidMessageHash() public { + // Send a message, then try to alter it's contents. + uint256 expectedNonce = _getNextMessageNonce(); + _sendTestMessageWithFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, 654456); + TeleporterMessage memory alteredMessage = TeleporterMessage({ + messageNonce: expectedNonce, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: hex"cafebabe" // The message would be expected to be empty + }); + + // Retry it - should fail. + vm.expectRevert(_formatTeleporterErrorMessage("invalid message hash")); + teleporterMessenger.retrySendCrossChainMessage(alteredMessage); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/SendCrossChainMessageTests.t.sol b/icm-contracts/contracts/teleporter/tests/SendCrossChainMessageTests.t.sol new file mode 100644 index 000000000..7ced64e8b --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/SendCrossChainMessageTests.t.sol @@ -0,0 +1,198 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterFeeInfo, + TeleporterMessageInput, + IWarpMessenger, + IERC20 +} from "./TeleporterMessengerTest.t.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; + +contract SendCrossChainMessageTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSendMessageNoFee() public { + // Arrange + uint256 expectedMessageNonce = _getNextMessageNonce(); + bytes32 expectedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + expectedMessageNonce + ); + TeleporterMessage memory expectedMessage = + _createMockTeleporterMessage(expectedMessageNonce, hex"deadbeef"); + TeleporterFeeInfo memory feeInfo = TeleporterFeeInfo(address(0), 0); + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: expectedMessage.destinationAddress, + feeInfo: feeInfo, + requiredGasLimit: expectedMessage.requiredGasLimit, + allowedRelayerAddresses: expectedMessage.allowedRelayerAddresses, + message: expectedMessage.message + }); + + // We have to mock the precompile call so that the test does not revert. + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(bytes32(0)) + ); + + // Expect the exact message to be passed to the precompile. + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.sendWarpMessage, (abi.encode(expectedMessage))) + ); + + // Expect the SendCrossChainMessage event to be emitted. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + expectedMessageID, messageInput.destinationBlockchainID, expectedMessage, feeInfo + ); + + // Act + teleporterMessenger.sendCrossChainMessage(messageInput); + + // Check receipt queue + uint256 queueSize = + teleporterMessenger.getReceiptQueueSize(messageInput.destinationBlockchainID); + assertEq(queueSize, 0); + } + + function testSendMessageWithFee() public { + // Arrange + // Construct the message to submit. + uint256 expectedMessageNonce = _getNextMessageNonce(); + TeleporterMessage memory expectedMessage = + _createMockTeleporterMessage(expectedMessageNonce, hex"deadbeef"); + TeleporterFeeInfo memory feeInfo = + TeleporterFeeInfo(address(_mockFeeAsset), 13131313131313131313); + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: expectedMessage.destinationAddress, + feeInfo: feeInfo, + requiredGasLimit: expectedMessage.requiredGasLimit, + allowedRelayerAddresses: expectedMessage.allowedRelayerAddresses, + message: expectedMessage.message + }); + + // We have to mock the precompile call so that the test does not revert. + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(bytes32(0)) + ); + + // Expect the exact message to be passed to the precompile. + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.sendWarpMessage, (abi.encode(expectedMessage))) + ); + + // Expect the SendCrossChainMessage event to be emitted. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + expectedMessageNonce + ), + messageInput.destinationBlockchainID, + expectedMessage, + feeInfo + ); + + // Expect the ERC20 contract transferFrom method to be called to transfer the fee. + vm.expectCall( + messageInput.feeInfo.feeTokenAddress, + abi.encodeCall( + IERC20.transferFrom, + (address(this), address(teleporterMessenger), messageInput.feeInfo.amount) + ) + ); + + // Act + teleporterMessenger.sendCrossChainMessage(messageInput); + } + + function testFeeAssetDoesNotExist() public { + address invalidFeeAsset = 0xb8be9140D8717f4a8fd7e8ae23C5668bc3A4B39c; + uint256 feeAmount = 4567; + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(invalidFeeAsset, feeAmount), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + // We expect a call to the fee asset address, but since we did not + // mock it there is no code there to execute. + vm.expectCall( + invalidFeeAsset, abi.encodeCall(IERC20.balanceOf, (address(teleporterMessenger))) + ); + vm.expectRevert(); + teleporterMessenger.sendCrossChainMessage(messageInput); + } + + function testFeeTransferFailure() public { + uint256 feeAmount = 4567; + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(address(_mockFeeAsset), feeAmount), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + vm.mockCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transferFrom, (address(this), address(teleporterMessenger), feeAmount) + ), + abi.encode(false) + ); + vm.expectCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transferFrom, (address(this), address(teleporterMessenger), feeAmount) + ) + ); + vm.expectRevert( + abi.encodeWithSelector( + SafeERC20.SafeERC20FailedOperation.selector, address(_mockFeeAsset) + ) + ); + teleporterMessenger.sendCrossChainMessage(messageInput); + } + + function testInvalidFeeAssetFailure() public { + address invalidFeeAsset = address(0); + uint256 feeAmount = 4567; + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: TeleporterFeeInfo(invalidFeeAsset, feeAmount), + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + vm.expectRevert(_formatTeleporterErrorMessage("zero fee asset contract address")); + teleporterMessenger.sendCrossChainMessage(messageInput); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/SendSpecifiedReceiptsTests.t.sol b/icm-contracts/contracts/teleporter/tests/SendSpecifiedReceiptsTests.t.sol new file mode 100644 index 000000000..ea4bc0e42 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/SendSpecifiedReceiptsTests.t.sol @@ -0,0 +1,261 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import { + TeleporterMessengerTest, + TeleporterMessage, + TeleporterMessageReceipt, + TeleporterFeeInfo, + IWarpMessenger, + IERC20 +} from "./TeleporterMessengerTest.t.sol"; + +contract SendSpecifiedReceiptsTest is TeleporterMessengerTest { + // The state of the contract gets reset before each + // test is run, with the `setUp()` function being called + // each time after deployment. + function setUp() public virtual override { + TeleporterMessengerTest.setUp(); + } + + function testSuccess() public { + // Mock receiving 3 messages from another chain + address[3] memory relayerRewardAddresses = [ + 0xa4CEE7d1aF6aDdDD33E3b1cC680AB84fdf1b6d1d, + 0x22d4002028f537599bE9f666d1c4Fa138522f9c8, + 0xb85e0651385876C3E3A1fF81ABf410ecf12f52f4 + ]; + + TeleporterMessageReceipt[] memory expectedReceipts = new TeleporterMessageReceipt[](3); + for (uint256 i; i < relayerRewardAddresses.length; ++i) { + _receiveTestMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + i + 1, + relayerRewardAddresses[i], + new TeleporterMessageReceipt[](0) + ); + expectedReceipts[i] = TeleporterMessageReceipt({ + receivedMessageNonce: i + 1, + relayerRewardAddress: relayerRewardAddresses[i] + }); + } + + // Mock sending a message back to that chain, which should include the 3 receipts. + uint256 expectedMessageNonce = _getNextMessageNonce(); + TeleporterMessage memory expectedMessage = TeleporterMessage({ + messageNonce: expectedMessageNonce, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: expectedReceipts, + message: new bytes(0) + }); + bytes32 expectedMessageID = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, DEFAULT_SOURCE_BLOCKCHAIN_ID, expectedMessageNonce + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + TeleporterFeeInfo memory feeInfo = TeleporterFeeInfo(address(0), 0); + emit SendCrossChainMessage( + expectedMessageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, expectedMessage, feeInfo + ); + bytes32 outboundMessageID = _sendTestMessageWithNoFee(DEFAULT_SOURCE_BLOCKCHAIN_ID); + assertEq(outboundMessageID, expectedMessageID); + assertEq( + teleporterMessenger.getRelayerRewardAddress( + teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 1 + ) + ), + relayerRewardAddresses[0] + ); + + TeleporterMessageReceipt[] memory newExpectedReceipts = new TeleporterMessageReceipt[](2); + newExpectedReceipts[0] = TeleporterMessageReceipt({ + receivedMessageNonce: 3, + relayerRewardAddress: relayerRewardAddresses[2] + }); + newExpectedReceipts[1] = TeleporterMessageReceipt({ + receivedMessageNonce: 1, + relayerRewardAddress: relayerRewardAddresses[0] + }); + + uint256 newExpectedMessageNonce = _getNextMessageNonce(); + bytes32 newExpectedMessageID = + teleporterMessenger.getNextMessageID(DEFAULT_SOURCE_BLOCKCHAIN_ID); + TeleporterMessage memory newExpectedMessage = TeleporterMessage({ + messageNonce: newExpectedMessageNonce, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + destinationAddress: address(0), + requiredGasLimit: uint256(0), + allowedRelayerAddresses: new address[](0), + receipts: newExpectedReceipts, + message: new bytes(0) + }); + + // Retry sending two of the receipts with {sendSpecifiedReceipts}. + bytes32[] memory receiptIDs = new bytes32[](2); + receiptIDs[0] = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 3 + ); + receiptIDs[1] = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 1 + ); + + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + newExpectedMessageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, newExpectedMessage, feeInfo + ); + + outboundMessageID = + _sendSpecifiedReceiptsWithNoFee(DEFAULT_SOURCE_BLOCKCHAIN_ID, receiptIDs); + + assertEq(outboundMessageID, newExpectedMessageID); + } + + function testMessageIDNotFromSourceBlockchain() public { + // Mock receiving a message from another chain + uint256 receivedMessageNonce = 987; + _receiveTestMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + receivedMessageNonce, + address(0), + new TeleporterMessageReceipt[](0) + ); + bytes32[] memory receiptIDs = new bytes32[](1); + receiptIDs[0] = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, receivedMessageNonce + ); + + // Call sendSpecifiedReceipts to try to send the receipts for those message IDs to a + // different chain than they were delivered by. + bytes32 otherBlockchainID = + bytes32(hex"11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff"); + vm.expectRevert(_formatTeleporterErrorMessage("message ID not from source blockchain")); + _sendSpecifiedReceiptsWithNoFee(otherBlockchainID, receiptIDs); + } + + function testDuplicateAllowed() public { + // Mock receiving a message from another chain + _receiveTestMessage( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + 1, + DEFAULT_RELAYER_REWARD_ADDRESS, + new TeleporterMessageReceipt[](0) + ); + + // Mock sending a message to that chain, which should include the 2 copies of the same receipt. + TeleporterMessageReceipt memory expectedReceipt = TeleporterMessageReceipt({ + receivedMessageNonce: 1, + relayerRewardAddress: DEFAULT_RELAYER_REWARD_ADDRESS + }); + TeleporterMessageReceipt[] memory expectedReceipts = new TeleporterMessageReceipt[](2); + expectedReceipts[0] = expectedReceipt; + expectedReceipts[1] = expectedReceipt; + uint256 expectedMessageNonce = _getNextMessageNonce(); + bytes32 expectedMessageID = + teleporterMessenger.getNextMessageID(DEFAULT_DESTINATION_BLOCKCHAIN_ID); + TeleporterMessage memory expectedMessage = TeleporterMessage({ + messageNonce: expectedMessageNonce, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: address(0), + requiredGasLimit: uint256(0), + allowedRelayerAddresses: new address[](0), + receipts: expectedReceipts, + message: new bytes(0) + }); + + bytes32[] memory messageIDs = new bytes32[](2); + messageIDs[0] = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 1 + ); + messageIDs[1] = teleporterMessenger.calculateMessageID( + DEFAULT_DESTINATION_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 1 + ); + + // Test sendSpecifiedReceipts when there are duplicate message IDs in the input. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit SendCrossChainMessage( + expectedMessageID, + DEFAULT_DESTINATION_BLOCKCHAIN_ID, + expectedMessage, + TeleporterFeeInfo(address(0), 0) + ); + + bytes32 outboundMessageID = + _sendSpecifiedReceiptsWithNoFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, messageIDs); + assertEq(outboundMessageID, expectedMessageID); + } + + function testMissingMessage() public { + // Mock receiving a message from another chain + _receiveTestMessage( + DEFAULT_SOURCE_BLOCKCHAIN_ID, + 1, + DEFAULT_RELAYER_REWARD_ADDRESS, + new TeleporterMessageReceipt[](0) + ); + + bytes32[] memory missingIDs = new bytes32[](1); + missingIDs[0] = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, 21 + ); + + // Try to send a receipt for an unreceived message from that chain - should fail. + vm.expectRevert(_formatTeleporterErrorMessage("receipt not found")); + _sendSpecifiedReceiptsWithNoFee(DEFAULT_DESTINATION_BLOCKCHAIN_ID, missingIDs); + } + + function _sendSpecifiedReceiptsWithFee( + bytes32 blockchainID, + bytes32[] memory messageIDs, + address feeAddress, + uint256 feeAmount + ) private returns (bytes32) { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(bytes32(0)) + ); + if (feeAmount > 0) { + vm.mockCall( + feeAddress, + abi.encodeCall( + IERC20.transferFrom, (address(this), address(teleporterMessenger), feeAmount) + ), + abi.encode(true) + ); + } + + TeleporterFeeInfo memory feeInfo = + TeleporterFeeInfo({feeTokenAddress: feeAddress, amount: feeAmount}); + + if (feeAmount > 0) { + // Expect the ERC20 contract transferFrom method to be called to transfer the fee. + vm.expectCall( + feeAddress, + abi.encodeCall( + IERC20.transferFrom, (address(this), address(teleporterMessenger), feeAmount) + ) + ); + } + + return teleporterMessenger.sendSpecifiedReceipts( + blockchainID, messageIDs, feeInfo, new address[](0) + ); + } + + function _sendSpecifiedReceiptsWithNoFee( + bytes32 blockchainID, + bytes32[] memory messageIDs + ) private returns (bytes32) { + return _sendSpecifiedReceiptsWithFee(blockchainID, messageIDs, address(0), 0); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/TeleporterMessengerTest.t.sol b/icm-contracts/contracts/teleporter/tests/TeleporterMessengerTest.t.sol new file mode 100644 index 000000000..baa401121 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/TeleporterMessengerTest.t.sol @@ -0,0 +1,281 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import { + TeleporterMessenger, + TeleporterMessage, + TeleporterMessageReceipt, + TeleporterMessageInput, + TeleporterFeeInfo, + IWarpMessenger, + WarpMessage +} from "../TeleporterMessenger.sol"; +import {UnitTestMockERC20} from "@mocks/UnitTestMockERC20.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; + +// Parent contract for TeleporterMessenger tests. Deploys a TeleporterMessenger +// instance in the test setup, and provides helper methods for sending and +// receiving empty mock messages. +contract TeleporterMessengerTest is Test { + bytes32 public constant DEFAULT_SOURCE_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + bytes32 public constant DEFAULT_DESTINATION_BLOCKCHAIN_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + address public constant DEFAULT_DESTINATION_ADDRESS = 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + uint256 public constant DEFAULT_REQUIRED_GAS_LIMIT = 1e6; + address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; + address public constant DEFAULT_RELAYER_REWARD_ADDRESS = + 0xa4CEE7d1aF6aDdDD33E3b1cC680AB84fdf1b6d1d; + + TeleporterMessenger public teleporterMessenger; + + UnitTestMockERC20 internal _mockFeeAsset; + + event BlockchainIDInitialized(bytes32 indexed blockchainID); + + event SendCrossChainMessage( + bytes32 indexed messageID, + bytes32 indexed destinationBlockchainID, + TeleporterMessage message, + TeleporterFeeInfo feeInfo + ); + + event AddFeeAmount(bytes32 indexed messageID, TeleporterFeeInfo updatedFeeInfo); + + event ReceiveCrossChainMessage( + bytes32 indexed messageID, + bytes32 indexed sourceBlockchainID, + address indexed deliverer, + address rewardRedeemer, + TeleporterMessage message + ); + + event MessageExecutionFailed( + bytes32 indexed messageID, bytes32 indexed sourceBlockchainID, TeleporterMessage message + ); + + event MessageExecuted(bytes32 indexed messageID, bytes32 indexed sourceBlockchainID); + + event ReceiptReceived( + bytes32 indexed messageID, + bytes32 indexed destinationBlockchainID, + address indexed relayerRewardAddress, + TeleporterFeeInfo feeInfo + ); + + event RelayerRewardsRedeemed(address indexed redeemer, address indexed asset, uint256 amount); + + function setUp() public virtual { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(DEFAULT_DESTINATION_BLOCKCHAIN_ID) + ); + + teleporterMessenger = new TeleporterMessenger(); + + // Blockchain ID should be 0 before it is initialized. + assertEq(teleporterMessenger.blockchainID(), bytes32(0)); + + // Initialize the blockchain ID. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit BlockchainIDInitialized(DEFAULT_DESTINATION_BLOCKCHAIN_ID); + teleporterMessenger.initializeBlockchainID(); + assertEq(teleporterMessenger.blockchainID(), DEFAULT_DESTINATION_BLOCKCHAIN_ID); + + _mockFeeAsset = new UnitTestMockERC20(); + } + + function testEmptyReceiptQueue() public { + assertEq(teleporterMessenger.getReceiptQueueSize(DEFAULT_DESTINATION_BLOCKCHAIN_ID), 0); + + vm.expectRevert("ReceiptQueue: index out of bounds"); + TeleporterMessageReceipt memory receipt = + teleporterMessenger.getReceiptAtIndex(DEFAULT_DESTINATION_BLOCKCHAIN_ID, 0); + assertEq(receipt.receivedMessageNonce, 0); + assertEq(receipt.relayerRewardAddress, address(0)); + } + + /* + * TEST UTILS / HELPERS + */ + + function _sendTestMessageWithFee( + bytes32 blockchainID, + uint256 feeAmount + ) internal returns (bytes32) { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(bytes32(0)) + ); + + address feeAsset = address(0); + if (feeAmount > 0) { + feeAsset = address(_mockFeeAsset); + } + TeleporterFeeInfo memory feeInfo = + TeleporterFeeInfo({feeTokenAddress: feeAsset, amount: feeAmount}); + + TeleporterMessageInput memory messageInput = TeleporterMessageInput({ + destinationBlockchainID: blockchainID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + feeInfo: feeInfo, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + message: new bytes(0) + }); + + if (feeAmount > 0) { + // Expect the ERC20 contract transferFrom method to be called to transfer the fee. + vm.expectCall( + address(_mockFeeAsset), + abi.encodeCall( + IERC20.transferFrom, (address(this), address(teleporterMessenger), feeAmount) + ) + ); + } + + return teleporterMessenger.sendCrossChainMessage(messageInput); + } + + function _sendTestMessageWithNoFee( + bytes32 blockchainID + ) internal returns (bytes32) { + return _sendTestMessageWithFee(blockchainID, 0); + } + + function _setUpSuccessGetVerifiedWarpMessageMock( + uint32 index, + WarpMessage memory warpMessage + ) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (index)), + abi.encode(warpMessage, true) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, (index)) + ); + } + + function _receiveTestMessage( + bytes32 sourceBlockchainID, + uint256 messageNonce, + address relayerRewardAddress, + TeleporterMessageReceipt[] memory receipts + ) internal { + // Construct the test message to be received. + TeleporterMessage memory messageToReceive = + _createMockTeleporterMessage(messageNonce, new bytes(0)); + messageToReceive.receipts = receipts; + + // Both the sender and destination address should be the teleporter contract address, + // mocking as if the universal deployer pattern was used. + WarpMessage memory warpMessage = + _createDefaultWarpMessage(sourceBlockchainID, abi.encode(messageToReceive)); + + // We have to mock the precompile call so that it doesn't revert in the tests. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Receive the message. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + teleporterMessenger.calculateMessageID( + sourceBlockchainID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, messageNonce + ), + warpMessage.sourceChainID, + address(this), + relayerRewardAddress, + messageToReceive + ); + teleporterMessenger.receiveCrossChainMessage(0, relayerRewardAddress); + } + + function _receiveMessageSentToEOA() + internal + returns (bytes32, address, TeleporterMessage memory) + { + // Create valid mock message data, we will mock out the execution of the + // message itself so it doesn't matter what it is. + bytes memory messageData = new bytes(1); + + // Construct the test message to be received. By default, the destination + // address will be the DEFAULT_DESTINATION_ADDRESS. + uint256 messageNonce = 9; + TeleporterMessage memory messageToReceive = + _createMockTeleporterMessage(messageNonce, messageData); + WarpMessage memory warpMessage = + _createDefaultWarpMessage(DEFAULT_SOURCE_BLOCKCHAIN_ID, abi.encode(messageToReceive)); + bytes32 messageID = teleporterMessenger.calculateMessageID( + DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_BLOCKCHAIN_ID, messageNonce + ); + + // We have to mock the precompile call so that it doesn't revert in the tests. + _setUpSuccessGetVerifiedWarpMessageMock(0, warpMessage); + + // Mock there being no code at the destination address which will be called + // when the message is executed. This mimics the default destination address being an EOA. + vm.etch(DEFAULT_DESTINATION_ADDRESS, new bytes(0)); + + // Receive the message - which should fail execution. + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit ReceiveCrossChainMessage( + messageID, + warpMessage.sourceChainID, + address(this), + DEFAULT_RELAYER_REWARD_ADDRESS, + messageToReceive + ); + vm.expectEmit(true, true, true, true, address(teleporterMessenger)); + emit MessageExecutionFailed(messageID, DEFAULT_SOURCE_BLOCKCHAIN_ID, messageToReceive); + teleporterMessenger.receiveCrossChainMessage(0, DEFAULT_RELAYER_REWARD_ADDRESS); + + return (DEFAULT_SOURCE_BLOCKCHAIN_ID, DEFAULT_DESTINATION_ADDRESS, messageToReceive); + } + + // Create a mock message to be used in tests. It should include no receipts + // because receipts are only valid if they refer to messages previously send + // to the origin chain. + function _createMockTeleporterMessage( + uint256 messageNonce, + bytes memory message + ) internal view returns (TeleporterMessage memory) { + return TeleporterMessage({ + messageNonce: messageNonce, + originSenderAddress: address(this), + destinationBlockchainID: DEFAULT_DESTINATION_BLOCKCHAIN_ID, + destinationAddress: DEFAULT_DESTINATION_ADDRESS, + requiredGasLimit: DEFAULT_REQUIRED_GAS_LIMIT, + allowedRelayerAddresses: new address[](0), + receipts: new TeleporterMessageReceipt[](0), + message: message + }); + } + + function _createDefaultWarpMessage( + bytes32 sourceBlockchainID, + bytes memory payload + ) internal view returns (WarpMessage memory) { + return WarpMessage({ + sourceChainID: sourceBlockchainID, + originSenderAddress: address(teleporterMessenger), + payload: payload + }); + } + + function _getNextMessageNonce() internal view returns (uint256) { + return teleporterMessenger.messageNonce() + 1; + } + + function _formatTeleporterErrorMessage( + bytes memory errorMessage + ) internal pure returns (bytes memory) { + return abi.encodePacked("TeleporterMessenger: ", errorMessage); + } +} diff --git a/icm-contracts/contracts/teleporter/tests/TestMessenger.sol b/icm-contracts/contracts/teleporter/tests/TestMessenger.sol new file mode 100644 index 000000000..147f8eeb8 --- /dev/null +++ b/icm-contracts/contracts/teleporter/tests/TestMessenger.sol @@ -0,0 +1,131 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {TeleporterMessageInput, TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; +import {SafeERC20TransferFrom, SafeERC20} from "@utilities/SafeERC20TransferFrom.sol"; +import {TeleporterRegistryOwnableAppUpgradeable} from + "@teleporter/registry/TeleporterRegistryOwnableAppUpgradeable.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {ReentrancyGuardUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ReentrancyGuardUpgradeable.sol"; + +/** + * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. + * DO NOT USE THIS CODE IN PRODUCTION. + */ + +/** + * @dev TestMessenger is test fixture contract that exercises sending and receiving + * messages cross chain. + */ +contract TestMessenger is ReentrancyGuardUpgradeable, TeleporterRegistryOwnableAppUpgradeable { + using SafeERC20 for IERC20; + + // Messages sent to this contract. + struct Message { + address sender; + string message; + } + + mapping(bytes32 sourceBlockchainID => Message message) private _messages; + + /** + * @dev Emitted when a message is submited to be sent. + */ + event SendMessage( + bytes32 indexed destinationBlockchainID, + address indexed destinationAddress, + address feeTokenAddress, + uint256 feeAmount, + uint256 requiredGasLimit, + string message + ); + + /** + * @dev Emitted when a new message is received from a given chain ID. + */ + event ReceiveMessage( + bytes32 indexed sourceBlockchainID, address indexed originSenderAddress, string message + ); + + constructor( + address teleporterRegistryAddress, + address teleporterManager, + uint256 minTeleporterVersion + ) initializer { + __ReentrancyGuard_init(); + __TeleporterRegistryOwnableApp_init( + teleporterRegistryAddress, teleporterManager, minTeleporterVersion + ); + } + + /** + * @dev Sends a message to another chain. + * @return The message ID of the newly sent message. + */ + function sendMessage( + bytes32 destinationBlockchainID, + address destinationAddress, + address feeTokenAddress, + uint256 feeAmount, + uint256 requiredGasLimit, + string calldata message + ) external nonReentrant returns (bytes32) { + // For non-zero fee amounts, first transfer the fee to this contract. + uint256 adjustedFeeAmount; + if (feeAmount > 0) { + adjustedFeeAmount = + SafeERC20TransferFrom.safeTransferFrom(IERC20(feeTokenAddress), feeAmount); + } + + emit SendMessage({ + destinationBlockchainID: destinationBlockchainID, + destinationAddress: destinationAddress, + feeTokenAddress: feeTokenAddress, + feeAmount: adjustedFeeAmount, + requiredGasLimit: requiredGasLimit, + message: message + }); + return _sendTeleporterMessage( + TeleporterMessageInput({ + destinationBlockchainID: destinationBlockchainID, + destinationAddress: destinationAddress, + feeInfo: TeleporterFeeInfo({feeTokenAddress: feeTokenAddress, amount: adjustedFeeAmount}), + requiredGasLimit: requiredGasLimit, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + } + + /** + * @dev Returns the current message from another chain. + * @return The sender of the message, and the message itself. + */ + function getCurrentMessage( + bytes32 sourceBlockchainID + ) external view returns (address, string memory) { + Message memory messageInfo = _messages[sourceBlockchainID]; + return (messageInfo.sender, messageInfo.message); + } + + /** + * @dev See {TeleporterRegistryAppUpgradeable-receiveTeleporterMessage}. + * + * Receives a message from another chain. + */ + function _receiveTeleporterMessage( + bytes32 sourceBlockchainID, + address originSenderAddress, + bytes memory message + ) internal override { + // Store the message. + string memory messageString = abi.decode(message, (string)); + _messages[sourceBlockchainID] = Message(originSenderAddress, messageString); + emit ReceiveMessage(sourceBlockchainID, originSenderAddress, messageString); + } +} diff --git a/tests/contracts/src/BatchCrossChainMessenger.sol b/icm-contracts/contracts/utilities/BatchCrossChainMessenger.sol similarity index 77% rename from tests/contracts/src/BatchCrossChainMessenger.sol rename to icm-contracts/contracts/utilities/BatchCrossChainMessenger.sol index 3d936b8fd..5b23388e3 100644 --- a/tests/contracts/src/BatchCrossChainMessenger.sol +++ b/icm-contracts/contracts/utilities/BatchCrossChainMessenger.sol @@ -3,13 +3,15 @@ // SPDX-License-Identifier: Ecosystem -pragma solidity 0.8.18; +pragma solidity 0.8.25; import {TeleporterMessageInput, TeleporterFeeInfo} from "@teleporter/ITeleporterMessenger.sol"; -import {SafeERC20TransferFrom, SafeERC20} from "@teleporter/SafeERC20TransferFrom.sol"; -import {TeleporterOwnerUpgradeable} from "@teleporter/upgrades/TeleporterOwnerUpgradeable.sol"; -import {IERC20} from "@openzeppelin/contracts@4.8.1/token/ERC20/IERC20.sol"; -import {ReentrancyGuard} from "@openzeppelin/contracts@4.8.1/security/ReentrancyGuard.sol"; +import {SafeERC20TransferFrom, SafeERC20} from "@utilities/SafeERC20TransferFrom.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {ReentrancyGuardUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ReentrancyGuardUpgradeable.sol"; +import {TeleporterRegistryOwnableAppUpgradeable} from + "@teleporter/registry/TeleporterRegistryOwnableAppUpgradeable.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. @@ -19,7 +21,10 @@ import {ReentrancyGuard} from "@openzeppelin/contracts@4.8.1/security/Reentrancy /** * @dev BatchCrossChainMessenger batches multiple Teleporter messages into a single transaction */ -contract BatchCrossChainMessenger is ReentrancyGuard, TeleporterOwnerUpgradeable { +contract BatchCrossChainMessenger is + ReentrancyGuardUpgradeable, + TeleporterRegistryOwnableAppUpgradeable +{ using SafeERC20 for IERC20; // Messages sent to this contract. @@ -51,8 +56,14 @@ contract BatchCrossChainMessenger is ReentrancyGuard, TeleporterOwnerUpgradeable constructor( address teleporterRegistryAddress, - address teleporterManager - ) TeleporterOwnerUpgradeable(teleporterRegistryAddress, teleporterManager) {} + address teleporterManager, + uint256 minTeleporterVersion + ) initializer { + __ReentrancyGuard_init(); + __TeleporterRegistryOwnableApp_init( + teleporterRegistryAddress, teleporterManager, minTeleporterVersion + ); + } /** * @dev Sends a message to another chain. @@ -87,7 +98,10 @@ contract BatchCrossChainMessenger is ReentrancyGuard, TeleporterOwnerUpgradeable TeleporterMessageInput({ destinationBlockchainID: destinationBlockchainID, destinationAddress: destinationAddress, - feeInfo: TeleporterFeeInfo({feeTokenAddress: feeTokenAddress, amount: adjustedFeeAmount}), + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: feeTokenAddress, + amount: adjustedFeeAmount + }), requiredGasLimit: requiredGasLimit, allowedRelayerAddresses: new address[](0), message: abi.encode(messages[i]) @@ -102,11 +116,9 @@ contract BatchCrossChainMessenger is ReentrancyGuard, TeleporterOwnerUpgradeable * @dev Returns the current message from another chain. * @return The sender of the message, and the message itself. */ - function getCurrentMessages(bytes32 sourceBlockchainID) - external - view - returns (string[] memory) - { + function getCurrentMessages( + bytes32 sourceBlockchainID + ) external view returns (string[] memory) { string[] memory messages = _messages[sourceBlockchainID]; return messages; } diff --git a/icm-contracts/contracts/utilities/CallUtils.sol b/icm-contracts/contracts/utilities/CallUtils.sol new file mode 100644 index 000000000..a2bc88915 --- /dev/null +++ b/icm-contracts/contracts/utilities/CallUtils.sol @@ -0,0 +1,60 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem +pragma solidity 0.8.25; + +library CallUtils { + /** + * @dev calls target address with exactly gasAmount gas and data as calldata + * or reverts if at least gasAmount gas is not available. + */ + function _callWithExactGas( + uint256 gasAmount, + address target, + bytes memory data + ) internal returns (bool) { + return _callWithExactGasAndValue(gasAmount, 0, target, data); + } + + /** + * @dev calls target address with exactly gasAmount gas and data as calldata + * or reverts if at least gasAmount gas is not available. + */ + function _callWithExactGasAndValue( + uint256 gasAmount, + uint256 value, + address target, + bytes memory data + ) internal returns (bool) { + require(gasleft() >= gasAmount, "CallUtils: insufficient gas"); + require(address(this).balance >= value, "CallUtils: insufficient value"); + + // If there is no code at the target, automatically consider the call to have failed since it + // doesn't have any effect on state. + if (target.code.length == 0) { + return false; + } + + // Call the target address of the message with the provided data and amount of gas. + // + // Assembly is used for the low-level call to avoid unnecessary expansion of the return data in memory. + // This prevents possible "return bomb" vectors where the external contract could force the caller + // to use an arbitrary amount of gas. See Solidity issue here: https://github.com/ethereum/solidity/issues/12306 + bool success; + // solhint-disable-next-line no-inline-assembly + assembly { + success := + call( + gasAmount, // gas provided to the call + target, // call target + value, // value transferred + add(data, 0x20), // input data - 0x20 needs to be added to an array because the first 32-byte slot contains the array length (0x20 in hex is 32 in decimal). + mload(data), // input data size - mload returns mem[p..(p+32)], which is the first 32-byte slot of the array. In this case, the array length. + 0, // output + 0 // output size + ) + } + return success; + } +} diff --git a/icm-contracts/contracts/utilities/ICMInitializable.sol b/icm-contracts/contracts/utilities/ICMInitializable.sol new file mode 100644 index 000000000..3db018372 --- /dev/null +++ b/icm-contracts/contracts/utilities/ICMInitializable.sol @@ -0,0 +1,10 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem +pragma solidity 0.8.25; + +enum ICMInitializable { + Allowed, + Disallowed +} diff --git a/icm-contracts/contracts/utilities/ReentrancyGuards.sol b/icm-contracts/contracts/utilities/ReentrancyGuards.sol new file mode 100644 index 000000000..b2fc55152 --- /dev/null +++ b/icm-contracts/contracts/utilities/ReentrancyGuards.sol @@ -0,0 +1,50 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * @dev Abstract contract that helps implement reentrancy guards between functions for sending and receiving. + * + * Consecutive calls for sending functions should work together, same for receive functions, but recursive calls + * should be detected as a reentrancy and revert. + * + * Calls between send and receive functions should also be allowed, but not in the case it ends up being a recursive + * send or receive call. For example the following should fail: send -> receive -> send. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract ReentrancyGuards { + // Send and Receive reentrancy guards + uint256 internal constant _NOT_ENTERED = 1; + uint256 internal constant _ENTERED = 2; + uint256 private _sendEntered; + uint256 private _receiveEntered; + + // senderNonReentrant modifier makes sure we can not reenter between sender calls. + // This modifier should be used for messenger sender functions that have external calls and do not want to allow + // recursive calls with other sender functions. + modifier senderNonReentrant() { + require(_sendEntered == _NOT_ENTERED, "ReentrancyGuards: sender reentrancy"); + _sendEntered = _ENTERED; + _; + _sendEntered = _NOT_ENTERED; + } + + // receiverNonReentrant modifier makes sure we can not reenter between receiver calls. + // This modifier should be used for messenger receiver functions that have external calls and do not want to allow + // recursive calls with other receiver functions. + modifier receiverNonReentrant() { + require(_receiveEntered == _NOT_ENTERED, "ReentrancyGuards: receiver reentrancy"); + _receiveEntered = _ENTERED; + _; + _receiveEntered = _NOT_ENTERED; + } + + constructor() { + _sendEntered = _NOT_ENTERED; + _receiveEntered = _NOT_ENTERED; + } +} diff --git a/icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol b/icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol new file mode 100644 index 000000000..ca221b7fc --- /dev/null +++ b/icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol @@ -0,0 +1,60 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; + +/** + * @dev Provides a wrapper used for calling an ERC20 transferFrom method + * to receive tokens to a contract from msg.sender. + * + * Checks the balance of the contract using the library before and after the call to safeTransferFrom, and + * returns balance increase. Designed for safely handling ERC20 "fee on transfer" and "burn on transfer" implementations. + * + * Note: A reentrancy guard must always be used when calling token.safeTransferFrom in order to + * prevent against possible "before-after" pattern vulnerabilities. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +library SafeERC20TransferFrom { + using SafeERC20 for IERC20; + + /** + * @dev Checks the balance of the contract before and after the call to safeTransferFrom, and returns the balance + * increase. Designed for safely handling ERC20 "fee on transfer" and "burn on transfer" implementations. + */ + // solhint-disable private-vars-leading-underscore + function safeTransferFrom(IERC20 erc20, uint256 amount) internal returns (uint256) { + return safeTransferFrom(erc20, msg.sender, amount); + } + // solhint-enable private-vars-leading-underscore + + /** + * @dev Checks the balance of the contract before and after the call to safeTransferFrom, and returns the balance + * increase. Designed for safely handling ERC20 "fee on transfer" and "burn on transfer" implementations. + * + * Supports passing arbitrary sender address values, allowing its use in ERC-2771 compliant meta-transactions. + * Note: Contracts that use this function must ensure that users cannot pass arbitrary addresses as + * the {from} address for the {transferFrom} call. Proper authorization (such as msg.sender) must + * be required to ensure no one can improperly transfer tokens from any address. + */ + // solhint-disable private-vars-leading-underscore + function safeTransferFrom( + IERC20 erc20, + address from, + uint256 amount + ) internal returns (uint256) { + uint256 balanceBefore = erc20.balanceOf(address(this)); + erc20.safeTransferFrom(from, address(this), amount); + uint256 balanceAfter = erc20.balanceOf(address(this)); + + require(balanceAfter > balanceBefore, "SafeERC20TransferFrom: balance not increased"); + + return balanceAfter - balanceBefore; + } + // solhint-enable private-vars-leading-underscore +} diff --git a/icm-contracts/contracts/utilities/SafeWrappedNativeTokenDeposit.sol b/icm-contracts/contracts/utilities/SafeWrappedNativeTokenDeposit.sol new file mode 100644 index 000000000..b3cc6d544 --- /dev/null +++ b/icm-contracts/contracts/utilities/SafeWrappedNativeTokenDeposit.sol @@ -0,0 +1,40 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IWrappedNativeToken} from "../ictt/interfaces/IWrappedNativeToken.sol"; + +/** + * @dev Provides a wrapper used for calling the {IWrappedNativeToken-deposit} method + * to deposit native tokens into the contract. + * + * Checks the balance of the contract before and after the call to deposit, and returns the balance + * increase. + * + * Note: A reentrancy guard must always be used when calling token.safeDeposit in order to + * prevent against possible "before-after" pattern vulnerabilities. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +library SafeWrappedNativeTokenDeposit { + /** + * @dev Checks the balance of the contract before and after the call to deposit, and returns the balance + * increase. + */ + // solhint-disable private-vars-leading-underscore + function safeDeposit(IWrappedNativeToken token, uint256 amount) internal returns (uint256) { + uint256 balanceBefore = token.balanceOf(address(this)); + token.deposit{value: amount}(); + uint256 balanceAfter = token.balanceOf(address(this)); + + require( + balanceAfter > balanceBefore, "SafeWrappedNativeTokenDeposit: balance not increased" + ); + + return balanceAfter - balanceBefore; + } + // solhint-enable private-vars-leading-underscore +} diff --git a/icm-contracts/contracts/utilities/SendReentrancyGuardUpgradeable.sol b/icm-contracts/contracts/utilities/SendReentrancyGuardUpgradeable.sol new file mode 100644 index 000000000..4332e0e9b --- /dev/null +++ b/icm-contracts/contracts/utilities/SendReentrancyGuardUpgradeable.sol @@ -0,0 +1,69 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; + +/** + * @dev Abstract contract that helps implement reentrancy guards for Avalanche interchain token transfer {_send} and {_sendAndCall} + * functions. + * + * The send methods must not allow reentry given that can make calls to external contracts such as {safeTransferFrom} + * and {safeDeposit}. However, the send methods should be allowed to be called from {receiveTeleporterMessage}, either + * as a part of processing a multi-hop transfer, or as a part of an external call made to process a "sendAndCall" + * message. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract SendReentrancyGuardUpgradeable is Initializable { + // solhint-disable private-vars-leading-underscore + /// @custom:storage-location erc7201:avalanche-ictt.storage.SendReentrancyGuard + struct SendReentrancyGuardStorage { + uint256 _sendEntered; + } + // solhint-enable private-vars-leading-underscore + + // keccak256(abi.encode(uint256(keccak256("avalanche-ictt.storage.SendReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff)); + bytes32 private constant _SEND_REENTRANCY_GUARD_STORAGE_LOCATION = + 0xd2f1ed38b7d242bfb8b41862afb813a15193219a4bc717f2056607593e6c7500; + + // solhint-disable ordering + function _getSendReentrancyGuardStorage() + private + pure + returns (SendReentrancyGuardStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := _SEND_REENTRANCY_GUARD_STORAGE_LOCATION + } + } + + uint256 private constant _NOT_ENTERED = 1; + uint256 private constant _ENTERED = 2; + + // sendNonReentrant modifier makes sure there is not reentry between {_send} or {_sendAndCall} calls. + modifier sendNonReentrant() { + SendReentrancyGuardStorage storage $ = _getSendReentrancyGuardStorage(); + require($._sendEntered == _NOT_ENTERED, "SendReentrancyGuard: send reentrancy"); + $._sendEntered = _ENTERED; + _; + $._sendEntered = _NOT_ENTERED; + } + + //solhint-disable-next-line func-name-mixedcase + function __SendReentrancyGuard_init() internal onlyInitializing { + __SendReentrnacyGuard_init_unchained(); + } + + //solhint-disable-next-line func-name-mixedcase + function __SendReentrnacyGuard_init_unchained() internal { + SendReentrancyGuardStorage storage $ = _getSendReentrancyGuardStorage(); + $._sendEntered = _NOT_ENTERED; + } + // solhint-enable ordering +} diff --git a/icm-contracts/contracts/utilities/TokenScalingUtils.sol b/icm-contracts/contracts/utilities/TokenScalingUtils.sol new file mode 100644 index 000000000..2f82150ad --- /dev/null +++ b/icm-contracts/contracts/utilities/TokenScalingUtils.sol @@ -0,0 +1,84 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem +pragma solidity 0.8.25; + +library TokenScalingUtils { + uint256 public constant MAX_TOKEN_DECIMALS = 18; + + /** + * @notice Scales the {amount} of home tokens to a TokenRemote instance's token scale. + * @param tokenMultiplier The token multiplier of the TokenRemote instance. + * @param multiplyOnRemote Whether the amount of home tokens will be multiplied on the remote, or divided. + * @param homeTokenAmount The amount of home tokens to scale. + */ + function applyTokenScale( + uint256 tokenMultiplier, + bool multiplyOnRemote, + uint256 homeTokenAmount + ) internal pure returns (uint256) { + return _scaleTokens(tokenMultiplier, multiplyOnRemote, homeTokenAmount, true); + } + + /** + * @notice Removes the TokenRemote instance's token scaling, and returns the corresponding + * amount of home tokens. + * @param tokenMultiplier The token multiplier of the TokenRemote instance. + * @param multiplyOnRemote Whether the amount of home tokens will be multiplied on the remote, or divided. + * @param remoteTokenAmount The amount of remote tokens to remove scaling from. + */ + function removeTokenScale( + uint256 tokenMultiplier, + bool multiplyOnRemote, + uint256 remoteTokenAmount + ) internal pure returns (uint256) { + return _scaleTokens(tokenMultiplier, multiplyOnRemote, remoteTokenAmount, false); + } + + /** + * @notice Takes both the home and remote token denominations and uses + * them to derive the token transferrer scaling multiplier values + * @param homeTokenDecimals The number of decimals of the home token. + * @param remoteTokenDecimals The number of decimals of the remote token. + */ + function deriveTokenMultiplierValues( + uint8 homeTokenDecimals, + uint8 remoteTokenDecimals + ) internal pure returns (uint256, bool) { + bool multiplyOnRemote = remoteTokenDecimals > homeTokenDecimals; + uint256 tokenMultiplier = 10 + ** ( + multiplyOnRemote + ? uint256(remoteTokenDecimals - homeTokenDecimals) + : uint256(homeTokenDecimals - remoteTokenDecimals) + ); + return (tokenMultiplier, multiplyOnRemote); + } + + /** + * @dev Scales {value} based on {tokenMultiplier} and if the amount is applying or + * removing the TokenRemote instance's token scale. + * Should be used for all tokens and fees being transferred to/from other L1s. + * @param tokenMultiplier The token multiplier of the TokenRemote instance. + * @param multiplyOnRemote Whether the amount of home tokens will be multiplied on the remote, or divided. + * @param amount The amount of tokens to scale. + * @param isSendToRemote If true, indicates the amount is being sent to the + * TokenRemote instance, so applies token scale. If false, indicates the amount is being + * sent back to the TokenHome instance, so removes token scale. + */ + function _scaleTokens( + uint256 tokenMultiplier, + bool multiplyOnRemote, + uint256 amount, + bool isSendToRemote + ) private pure returns (uint256) { + // Multiply when multiplyOnRemote and isSendToRemote are + // both true or both false. + if (multiplyOnRemote == isSendToRemote) { + return amount * tokenMultiplier; + } + // Otherwise divide. + return amount / tokenMultiplier; + } +} diff --git a/icm-contracts/contracts/utilities/tests/ReentrancyGuardsTests.t.sol b/icm-contracts/contracts/utilities/tests/ReentrancyGuardsTests.t.sol new file mode 100644 index 000000000..3961bf4db --- /dev/null +++ b/icm-contracts/contracts/utilities/tests/ReentrancyGuardsTests.t.sol @@ -0,0 +1,133 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ReentrancyGuards} from "@utilities/ReentrancyGuards.sol"; + +contract ReentrancyGuardsTests is Test { + SampleMessenger internal _sampleMessenger; + + function setUp() public virtual { + _sampleMessenger = new SampleMessenger(); + } + + function testConsecutiveSendSuccess() public { + _sampleMessenger.sendAndCall(new bytes(0)); + _sampleMessenger.sendMessage(); + _sampleMessenger.sendAndCall(new bytes(0)); + assertEq(_sampleMessenger.nonce(), 3); + } + + function testConsecutiveReceiveSuccess() public { + _sampleMessenger.receiveAndCall(new bytes(0)); + _sampleMessenger.receiveMessage(); + _sampleMessenger.receiveAndCall(new bytes(0)); + assertEq(_sampleMessenger.nonce(), 3); + } + + function testRecursiveSendFails() public { + // First we check when a send function calls another send function, which should fail. + bytes memory sendMsg = abi.encodeCall(SampleMessenger.sendMessage, ()); + vm.expectRevert("send failed"); + _sampleMessenger.sendAndCall(sendMsg); + + // We also need to check that we fail if a send function calls a receive function, + // and then calls send function again + bytes memory receiveMsg = abi.encodeCall(SampleMessenger.receiveAndCall, (sendMsg)); + vm.expectRevert("send failed"); + _sampleMessenger.sendAndCall(receiveMsg); + } + + function testRecursiveReceiveFails() public { + // First we check when a receive function calls another receive function, which should fail. + bytes memory receiveMsg = abi.encodeCall(SampleMessenger.receiveMessage, ()); + vm.expectRevert("receive failed"); + _sampleMessenger.receiveAndCall(receiveMsg); + + // We also need to check that we fail if a receive function calls a send function, + // and then calls receive function again + bytes memory sendMsg = abi.encodeCall(SampleMessenger.sendAndCall, (receiveMsg)); + vm.expectRevert("receive failed"); + _sampleMessenger.receiveAndCall(sendMsg); + } + + function testSendCallsReceiveSuccess() public { + bytes memory message = abi.encodeCall(SampleMessenger.receiveMessage, ()); + _sampleMessenger.sendAndCall(message); + assertEq(_sampleMessenger.nonce(), 2); + } + + function testReceiveCallsSendSuccess() public { + bytes memory message = abi.encodeCall(SampleMessenger.sendMessage, ()); + _sampleMessenger.receiveAndCall(message); + assertEq(_sampleMessenger.nonce(), 2); + } + + function testRecursiveDirectSendFails() public { + // We want to check sending recursively by directly making a function call and not low level call also fails. + vm.expectRevert("ReentrancyGuards: sender reentrancy"); + _sampleMessenger.sendRecursive(); + + assertEq(_sampleMessenger.nonce(), 0); + } + + function testRecursiveDirectReceiveFails() public { + // We want to check receiving recursively by directly making a function call and not low level call also fails. + vm.expectRevert("ReentrancyGuards: receiver reentrancy"); + _sampleMessenger.receiveRecursive(); + + assertEq(_sampleMessenger.nonce(), 0); + } +} + +contract SampleMessenger is ReentrancyGuards { + uint256 public nonce; + + constructor() { + nonce = 0; + } + + function sendAndCall( + bytes memory message + ) public senderNonReentrant { + nonce++; + if (message.length > 0) { + // solhint-disable-next-line avoid-low-level-calls + (bool success,) = address(this).call(message); + require(success, "send failed"); + } + } + + function sendMessage() public senderNonReentrant { + nonce++; + } + + function sendRecursive() public senderNonReentrant { + nonce++; + sendMessage(); + } + + function receiveAndCall( + bytes memory message + ) public receiverNonReentrant { + nonce++; + if (message.length > 0) { + // solhint-disable-next-line avoid-low-level-calls + (bool success,) = address(this).call(message); + require(success, "receive failed"); + } + } + + function receiveMessage() public receiverNonReentrant { + nonce++; + } + + function receiveRecursive() public receiverNonReentrant { + nonce++; + receiveMessage(); + } +} diff --git a/icm-contracts/contracts/validator-manager/ACP99Manager.sol b/icm-contracts/contracts/validator-manager/ACP99Manager.sol new file mode 100644 index 000000000..095e13e87 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/ACP99Manager.sol @@ -0,0 +1,70 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IACP99Manager, PChainOwner} from "./interfaces/IACP99Manager.sol"; + +/* + * @title ACP99Manager + * @notice The ACP99Manager interface represents the functionality for sovereign L1 + * validator management, as specified in ACP-77. + * + * @dev ACP99Manager defines the private functions specified in ACP-99. + * The counterpart to this contract is IACP99Manager, which defines the public functions specified in ACP-99. + * https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/99-validatorsetmanager-contract + */ +abstract contract ACP99Manager is IACP99Manager { + // solhint-disable ordering + + /** + * @notice Initiates validator registration by issuing a RegisterL1ValidatorMessage. The validator should + * not be considered active until completeValidatorRegistration is called. + * + * Emits an {InitiatedValidatorRegistration} event on success. + * + * @param nodeID The ID of the node to add to the L1. + * @param blsPublicKey The BLS public key of the validator. + * @param remainingBalanceOwner The remaining balance owner of the validator. + * @param disableOwner The disable owner of the validator. + * @param weight The weight of the node on the L1. + * @return validationID The ID of the registered validator. + */ + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) internal virtual returns (bytes32 validationID); + + /** + * @notice Initiates validator removal by issuing a L1ValidatorWeightMessage with the weight set to zero. + * The validator should be considered inactive as soon as this function is called. + * + * Emits an {InitiatedValidatorRemoval} on success. + * + * @param validationID The ID of the validator to remove. + */ + function _initiateValidatorRemoval( + bytes32 validationID + ) internal virtual; + + /** + * @notice Initiates a validator weight update by issuing an L1ValidatorWeightMessage with a nonzero weight. + * The validator weight change should not have any effect until completeValidatorWeightUpdate is successfully called. + * + * Emits an {InitiatedValidatorWeightUpdate} event on success. + * + * @param validationID The ID of the validator to modify. + * @param weight The new weight of the validator. + * @return nonce The validator nonce associated with the weight change. + * @return messageID The ID of the L1ValidatorWeightMessage used to update the validator's weight. + */ + function _initiateValidatorWeightUpdate( + bytes32 validationID, + uint64 weight + ) internal virtual returns (uint64 nonce, bytes32 messageID); +} diff --git a/icm-contracts/contracts/validator-manager/ERC20TokenStakingManager.sol b/icm-contracts/contracts/validator-manager/ERC20TokenStakingManager.sol new file mode 100644 index 000000000..60c7b60f6 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/ERC20TokenStakingManager.sol @@ -0,0 +1,161 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {StakingManager} from "./StakingManager.sol"; +import {StakingManagerSettings} from "./interfaces/IStakingManager.sol"; +import {PChainOwner} from "./ACP99Manager.sol"; +import {IERC20TokenStakingManager} from "./interfaces/IERC20TokenStakingManager.sol"; +import {IERC20Mintable} from "./interfaces/IERC20Mintable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; + +/** + * @dev Implementation of the {IERC20TokenStakingManager} interface. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract ERC20TokenStakingManager is Initializable, StakingManager, IERC20TokenStakingManager { + using SafeERC20 for IERC20Mintable; + using SafeERC20TransferFrom for IERC20Mintable; + + // solhint-disable private-vars-leading-underscore + /// @custom:storage-location erc7201:avalanche-icm.storage.ERC20TokenStakingManager + struct ERC20TokenStakingManagerStorage { + IERC20Mintable _token; + } + // solhint-enable private-vars-leading-underscore + + // keccak256(abi.encode(uint256(keccak256("avalanche-icm.storage.ERC20TokenStakingManager")) - 1)) & ~bytes32(uint256(0xff)); + bytes32 public constant ERC20_STAKING_MANAGER_STORAGE_LOCATION = + 0x6e5bdfcce15e53c3406ea67bfce37dcd26f5152d5492824e43fd5e3c8ac5ab00; + + // solhint-disable ordering + function _getERC20StakingManagerStorage() + private + pure + returns (ERC20TokenStakingManagerStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := ERC20_STAKING_MANAGER_STORAGE_LOCATION + } + } + + constructor( + ICMInitializable init + ) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initialize the ERC20 token staking manager + * @param settings Initial settings for the PoS validator manager + * @param token The ERC20 token to be staked + */ + function initialize( + StakingManagerSettings calldata settings, + IERC20Mintable token + ) external initializer { + __ERC20TokenStakingManager_init(settings, token); + } + + // solhint-disable-next-line func-name-mixedcase + function __ERC20TokenStakingManager_init( + StakingManagerSettings calldata settings, + IERC20Mintable token + ) internal onlyInitializing { + __StakingManager_init(settings); + __ERC20TokenStakingManager_init_unchained(token); + } + + // solhint-disable-next-line func-name-mixedcase + function __ERC20TokenStakingManager_init_unchained( + IERC20Mintable token + ) internal onlyInitializing { + ERC20TokenStakingManagerStorage storage $ = _getERC20StakingManagerStorage(); + if (address(token) == address(0)) { + revert ZeroAddress(); + } + $._token = token; + } + + /** + * @notice See {IERC20TokenStakingManager-initiateValidatorRegistration} + */ + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount, + address rewardRecipient + ) external nonReentrant returns (bytes32) { + return _initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: delegationFeeBips, + minStakeDuration: minStakeDuration, + stakeAmount: stakeAmount, + rewardRecipient: rewardRecipient + }); + } + + /** + * @notice See {IERC20TokenStakingManager-initiateDelegatorRegistration} + */ + function initiateDelegatorRegistration( + bytes32 validationID, + uint256 delegationAmount, + address rewardRecipient + ) external nonReentrant returns (bytes32) { + return _initiateDelegatorRegistration( + validationID, _msgSender(), delegationAmount, rewardRecipient + ); + } + + /** + * @notice Returns the ERC20 token being staked + */ + function erc20() external view returns (IERC20Mintable) { + return _getERC20StakingManagerStorage()._token; + } + + /** + * @notice See {StakingManager-_lock} + * Note: Must be guarded with reentrancy guard for safe transfer from. + */ + function _lock( + uint256 value + ) internal virtual override returns (uint256) { + return _getERC20StakingManagerStorage()._token.safeTransferFrom(value); + } + + /** + * @notice See {StakingManager-_unlock} + * Note: Must be guarded with reentrancy guard for safe transfer. + */ + function _unlock(address to, uint256 value) internal virtual override { + _getERC20StakingManagerStorage()._token.safeTransfer(to, value); + } + + /** + * @notice See {StakingManager-_reward} + */ + function _reward(address account, uint256 amount) internal virtual override { + ERC20TokenStakingManagerStorage storage $ = _getERC20StakingManagerStorage(); + $._token.mint(account, amount); + } +} diff --git a/icm-contracts/contracts/validator-manager/ExampleRewardCalculator.sol b/icm-contracts/contracts/validator-manager/ExampleRewardCalculator.sol new file mode 100644 index 000000000..49e02ed89 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/ExampleRewardCalculator.sol @@ -0,0 +1,48 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IRewardCalculator} from "./interfaces/IRewardCalculator.sol"; + +contract ExampleRewardCalculator is IRewardCalculator { + uint256 public constant SECONDS_IN_YEAR = 31536000; + + uint8 public constant UPTIME_REWARDS_THRESHOLD_PERCENTAGE = 80; + + uint16 public constant BIPS_CONVERSION_FACTOR = 10000; + + uint64 public immutable rewardBasisPoints; + + constructor( + uint64 rewardBasisPoints_ + ) { + rewardBasisPoints = rewardBasisPoints_; + } + + /** + * @notice A linear, non-compounding reward calculation that rewards a set percentage of tokens per year. + * See {IRewardCalculator-calculateReward} + */ + function calculateReward( + uint256 stakeAmount, + uint64 validatorStartTime, + uint64 stakingStartTime, + uint64 stakingEndTime, + uint64 uptimeSeconds + ) external view returns (uint256) { + // Equivalent to uptimeSeconds/(validator.endTime - validator.startTime) < UPTIME_REWARDS_THRESHOLD_PERCENTAGE/100 + // Rearranged to prevent integer division truncation. + if ( + uptimeSeconds * 100 + < (stakingEndTime - validatorStartTime) * UPTIME_REWARDS_THRESHOLD_PERCENTAGE + ) { + return 0; + } + + return (stakeAmount * rewardBasisPoints * (stakingEndTime - stakingStartTime)) + / SECONDS_IN_YEAR / BIPS_CONVERSION_FACTOR; + } +} diff --git a/icm-contracts/contracts/validator-manager/MigratingFromV1.md b/icm-contracts/contracts/validator-manager/MigratingFromV1.md new file mode 100644 index 000000000..ed897bf4b --- /dev/null +++ b/icm-contracts/contracts/validator-manager/MigratingFromV1.md @@ -0,0 +1,24 @@ +# Migrating From V1 Validator Manager Contracts + +The V1 Validator Manager contracts are implemented as a single deployed contract consisting of multiple contracts related through inheritance. The V2 Validator Manager, on the other hand, consists of multiple deployed contracts that interact via external function calls. + +> Note: This guide only applies to validator manager contracts at or above [validator-manager-v1.0.0](https://github.com/ava-labs/icm-contracts/releases/tag/validator-manager-v1.0.0). Contracts at commits before then must use other methods to convert to V2. + +## Migrating Proof-of-Authority + +In the V2 contracts, Proof-of-Authority validator management is implemented by `PoAManager` in conjunction with `ValidatorManager`. After deploying the standalone `PoAManager` contract, ownership of the `ValidatorManager` should be transferred over to it by calling `ValidatorManager.transferOwnership`, and providing the `PoAManager`'s address as the argument. Note that there is no requirement that the owner of V2 `PoAManager` be the same owner as the V1 `PoAValidatorManager`. + +The V1 `PoAValidatorManager` does not track any state, so migrating from a V1 to V2 therefore only requires migrating the state variables that track validators. The helper method `migrateFromV1` is provided for this purpose. The general steps are as follows: + +1. Upgrade the proxy contract's implementation to a newly deployed V2 `ValidatorManager` using standard methods +2. For each validator (active or expired), call `migrateFromV1` with its `validationID`. The `receivedNonce` argument can be set to 0, since V1 `PoAValidatorManager`s do not support weight changes. + +Some notes on this process: +- `migrateFromV1` may only be called once per `validationID`. Any active validators will not be able to be removed until they are migrated. +- It is up to the contract owner to track all of the `validationID`s to be migrated. This is because Solidity mappings are not iterable, so there is no getter to retreive all `validationID`s as a batch. + +## Migrating Proof-of-Stake + +**Migrating from a V1 `PoSValidatorManager` deployment to a V2 Proof-of-Stake Validator Manager is not supported.** + +Similar to the V2 Proof-of-Authority implementation, V2 Proof-of-Stake Validator Managers consist of two deployed contracts: an instance of a concrete implementation of `StakingManager`, and an instance of a `ValidatorManager`. However, unlike the V1 `PoAValidatorManager`, the V1 `PoSValidatorManager` does maintain state in order to track delegators, redeemable staking rewards, etc. Because the V2 `StakingManager` is a standalone contract that does not share state with `ValidatorManager`, migrating from a V1 `PoSValidatorManager` to a V2 `StakingManager` would require replicating state from one contract to another. \ No newline at end of file diff --git a/icm-contracts/contracts/validator-manager/NativeTokenStakingManager.sol b/icm-contracts/contracts/validator-manager/NativeTokenStakingManager.sol new file mode 100644 index 000000000..135c6d7ae --- /dev/null +++ b/icm-contracts/contracts/validator-manager/NativeTokenStakingManager.sol @@ -0,0 +1,115 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {StakingManager} from "./StakingManager.sol"; +import {StakingManagerSettings} from "./interfaces/IStakingManager.sol"; +import {PChainOwner} from "./ACP99Manager.sol"; +import {INativeTokenStakingManager} from "./interfaces/INativeTokenStakingManager.sol"; +import {INativeMinter} from "@subnet-evm/INativeMinter.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {Address} from "@openzeppelin/contracts@5.0.2/utils/Address.sol"; +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; + +/** + * @dev Implementation of the {INativeTokenStakingManager} interface. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract NativeTokenStakingManager is Initializable, StakingManager, INativeTokenStakingManager { + using Address for address payable; + + INativeMinter public constant NATIVE_MINTER = + INativeMinter(0x0200000000000000000000000000000000000001); + + constructor( + ICMInitializable init + ) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initialize the native token staking manager + * @param settings Initial settings for the PoS validator manager + */ + // solhint-disable ordering + function initialize( + StakingManagerSettings calldata settings + ) external initializer { + __NativeTokenStakingManager_init(settings); + } + + // solhint-disable-next-line func-name-mixedcase + function __NativeTokenStakingManager_init( + StakingManagerSettings calldata settings + ) internal onlyInitializing { + __StakingManager_init(settings); + } + + // solhint-disable-next-line func-name-mixedcase, no-empty-blocks + function __NativeTokenStakingManager_init_unchained() internal onlyInitializing {} + + /** + * @notice See {INativeTokenStakingManager-initiateValidatorRegistration}. + */ + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + address rewardRecipient + ) external payable nonReentrant returns (bytes32) { + return _initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: delegationFeeBips, + minStakeDuration: minStakeDuration, + stakeAmount: msg.value, + rewardRecipient: rewardRecipient + }); + } + + /** + * @notice See {INativeTokenStakingManager-initiateDelegatorRegistration}. + */ + function initiateDelegatorRegistration( + bytes32 validationID, + address rewardRecipient + ) external payable nonReentrant returns (bytes32) { + return + _initiateDelegatorRegistration(validationID, _msgSender(), msg.value, rewardRecipient); + } + + /** + * @notice See {StakingManager-_lock} + */ + function _lock( + uint256 value + ) internal virtual override returns (uint256) { + return value; + } + + /** + * @notice See {StakingManager-_unlock} + */ + function _unlock(address to, uint256 value) internal virtual override { + payable(to).sendValue(value); + } + + /** + * @notice See {StakingManager-_reward} + */ + function _reward(address account, uint256 amount) internal virtual override { + NATIVE_MINTER.mintNativeCoin(account, amount); + } +} diff --git a/icm-contracts/contracts/validator-manager/PoAManager.sol b/icm-contracts/contracts/validator-manager/PoAManager.sol new file mode 100644 index 000000000..924469729 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/PoAManager.sol @@ -0,0 +1,94 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IPoAManager} from "./interfaces/IPoAManager.sol"; +import {IValidatorManagerExternalOwnable} from "./interfaces/IValidatorManagerExternalOwnable.sol"; +import {PChainOwner} from "./interfaces/IACP99Manager.sol"; +import {Ownable} from "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; + +/** + * @dev Implementation of the {IPoAManager} interface. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract PoAManager is IPoAManager, Ownable { + IValidatorManagerExternalOwnable private immutable _manager; + + constructor(address owner, IValidatorManagerExternalOwnable validatorManager) Ownable(owner) { + _manager = validatorManager; + } + + /** + * @notice See {IPoAManager-initiateValidatorRegistration}. + */ + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) external onlyOwner returns (bytes32) { + return _manager.initiateValidatorRegistration( + nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight + ); + } + + /** + * @notice See {IPoAManager-initiateValidatorRemoval}. + */ + function initiateValidatorRemoval( + bytes32 validationID + ) external onlyOwner { + return _manager.initiateValidatorRemoval(validationID); + } + + /** + * @notice See {IPoAManager-initiateValidatorWeightUpdate}. + */ + function initiateValidatorWeightUpdate( + bytes32 validationID, + uint64 newWeight + ) external onlyOwner returns (uint64, bytes32) { + return _manager.initiateValidatorWeightUpdate(validationID, newWeight); + } + + /** + * @notice See {IPoAManager-completeValidatorRegistration}. + */ + function completeValidatorRegistration( + uint32 messageIndex + ) external returns (bytes32) { + return _manager.completeValidatorRegistration(messageIndex); + } + + /** + * @notice See {IPoAManager-completeValidatorRemoval}. + */ + function completeValidatorRemoval( + uint32 messageIndex + ) external returns (bytes32) { + return _manager.completeValidatorRemoval(messageIndex); + } + + /** + * @notice See {IPoAManager-completeValidatorWeightUpdate}. + */ + function completeValidatorWeightUpdate( + uint32 messageIndex + ) external returns (bytes32, uint64) { + return _manager.completeValidatorWeightUpdate(messageIndex); + } + + /** + * @notice See {IPoAManager-transferValidatorManagerOwnership}. + */ + function transferValidatorManagerOwnership( + address newOwner + ) external onlyOwner { + _manager.transferOwnership(newOwner); + } +} diff --git a/icm-contracts/contracts/validator-manager/PoAMigration.md b/icm-contracts/contracts/validator-manager/PoAMigration.md new file mode 100644 index 000000000..163862e20 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/PoAMigration.md @@ -0,0 +1,55 @@ +# Migrating from PoA to PoS + +The Validator Manager contracts support migrating from a Proof-of-Authority security mechanism to Proof-of-Stake after the initial deployment. The contracts implement a "hard migration" from PoA to PoS at the point of migration, at which time existing PoA validators lose any special privileges. + +## Migration Guide + +Migrating from PoA to PoS consists of the following steps: + +### 1. Deploy `PoAManager`. +The `PoAManager` is deployed as a standalone contract, separate from the `ValidatorManager`. During deployment, the address of the `ValidatorManager` is provided as a constructor argument to the `PoAManager`, which then delegates relevant calls to the underlying `ValidatorManager`. + +- The **owner of the `PoAManager`** manages the validator set by invoking: + - `initiateValidatorRegistration` + - `initiateValidatorRemoval` + - `initiateValidatorWeightUpdate` + - `transferUnderlyingValidatorManagerOwnership` + +- The following functions are **permissionless** and may be called by anyone: + - `completeValidatorRegistration` + - `completeValidatorRemoval` + - `completeValidatorWeightUpdate` + +After the `PoAManager` is deployed, the desired PoA validators may be registered. See [below](#selecting-weights) for details on how to select the PoA validator weights. + +### 2. Deploy `StakingManager`. + +The `StakingManager` is deployed as a standlone contract, separate from `ValidatorManager`. The `ValidatorManager` is provided as a constructor argument to the `StakingManager`, however they will not be able to interact until step 3 below is completed. + +The `StakingManager` constructor also takes as an argument the `weightToValueFactor` used to convert between the value of the staked asset and the corresponding validator weight. See [below](#selecting-weights) for details on how to select this factor. + +### 3. Transfer ownership of `ValidatorManager` to the `StakingManager`'s address. + +Ownership of the underlying `ValidatorManager` can be transferred from the `PoAManager` to the `StakingManager` by calling `transferValidatorManagerOwnership` on the `PoAManager` from the `PoAManager`'s owner. Once this is done, the `StakingManager` may update the L1's validator set via the `ValidatorManager`. + +### 4. Remove PoA validators in stages. + +Once ownership is transferred, PoA validators may be removed by *anyone* as long as churn limits are not violated, which are in place to mitigate against catastrophic consensus failure. + +#### Permissionless Removal of PoA Validators + +Existing PoA validators can be removed by anybody, whereas PoS validators can only be removed by the validator owner. This is done in order to enable a sharp, step transition from PoS to PoA in which PoA validators are expected to be removed quickly, so long as churn limits aren't violated. + +To better understand this design choice, consider an alternative implementation in which only the former PoA `admin` is able to remove PoA validators. If the PoA validator becomes inactive but remains in the validator set, then their validator weight would persist, potentially causing stability issues on the L1. The L1 would require action on the part of the `admin`, who contrary to a PoS validator, does not have any staked value in bond. + +On the flip side, the current approach allows a fast-acting bad actor with sufficient access to the staking asset to register themselves as a validator then remove each of the PoA validators in turn. This can be mitigated by controlling the supply of the staking asset around migration time, tuned to the selected `weightToValueFactor` (see [below](#selecting-weights)). + +## Selecting Weights + +When migrating from PoA to PoS, the ratio between the total weight of the PoA validator set and the the total *available* weight that is stakeable by PoS validators (i.e. the supply of the staking asset) is critical. The higher this ratio, the slower the effective transition to a fully PoS model will be. This is due to churn limits, which have a ceiling of 20% validator weight change within a given configurable churn period. For example, if an L1 consists of 5 PoA validators each with weight 100, at most `5 * 100 * 20% = 100` of validator weight may be changed in a single period. That may correspond to the removal of a single PoA validator, or the addition of 100 weight's worth of PoS validators, but not both. + +> Note: Since PoA validators may be removed by [anyone](#permissionless-removal-of-poa-validators), in practice only the weight of the smallest PoA validator is relevant to the PoA to PoS weight ratio. Following the same math as above, in order to remove the final PoA validator, the total weight of the PoS validators must be at least 4x the PoA validator's weight. + +To implement the desired PoA to PoS transition dynamics, this ratio should be tuned against the PoA validator set's weight **ahead of migration**. This should be done by carefully selecting the PoA validator's initial weights, and the `weightToValueFactor` such that the equivalent weight of the total supply of the staked asset is in the desired ratio to the PoA validator set's weight. The PoA validator weights may also be changed ahead of migration, though the rate of weight change is limited by churn restrictions. After migration, PoA validator weights may not be changed. + +Extending our above example of 5 PoA validators each with weight 100, suppose the total supply of the staking asset at migration time is `1000`, and `weightToValueFactor=10`. Then, the maximum PoS weight available is `1000/10 = 100`, yielding a PoA to PoS weight ratio of 5 to 1. \ No newline at end of file diff --git a/icm-contracts/contracts/validator-manager/README.md b/icm-contracts/contracts/validator-manager/README.md new file mode 100644 index 000000000..88eff26a7 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/README.md @@ -0,0 +1,217 @@ +# Validator Manager Contracts + +The contracts in this directory define the Validator Manager used to manage Avalanche L1 validators, as defined in [ACP-77](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets). They comply with [ACP-99](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/99-validatorsetmanager-contract), which specifies the standard minimal functionality that Validator Managers should implement. The contracts in this directory are are related as follows: + +```mermaid +--- + config: + class: + hideEmptyMembersBox: true +--- +classDiagram +class ACP99Manager { + +initializeValidatorSet() + +completeValidatorRegistration() + +completeValidatorRemoval() + +completeValidatorWeightUpdate() + -_initiateValidatorRegistration() + -_initiateValidatorRemoval() + -_initiateValidatorWeightUpdate() +} +<> ACP99Manager + +class ValidatorManager { + +initializeValidatorSet() + +completeValidatorRegistration() onlyOwner + +completeValidatorRemoval() onlyOwner + +completeValidatorWeightUpdate() onlyOwner + +initiateValidatorRegistration() onlyOwner + +initiateValidatorRemoval() onlyOwner + +initiateValidatorWeightUpdate() onlyOwner +} + +class PoAManager { + +completeValidatorRegistration() + +completeValidatorRemoval() + +completeValidatorWeightUpdate() + +initiateValidatorRegistration() onlyOwner + +initiateValidatorRemoval() onlyOwner + +initiateValidatorWeightUpdate() onlyOwner + +transferValidatorManagerOwnership() onlyOwner +} + +class StakingManager { + +completeValidatorRegistration() + +initiateValidatorRemoval() + +completeValidatorRemoval() + +completeDelegatorRegistration() + +initiateDelegatorRemoval() + +completeDelegatorRemoval() + -_initiateValidatorRegistration() + -_initiateDelegatorRegistration() +} +<> StakingManager +class ERC20TokenStakingManager { + +initiateValidatorRegistration() + +initiateDelegatorRegistration() +} +class NativeTokenStakingManager { + +initiateValidatorRegistration() payable + +initiateDelegatorRegistration() payable +} + +ACP99Manager <|-- ValidatorManager +ValidatorManager --o PoAManager : owner +ValidatorManager --o StakingManager : owner +StakingManager <|-- ERC20TokenStakingManager +StakingManager <|-- NativeTokenStakingManager +``` + +## A Note on Nomenclature + +The contracts in this directory are only useful to L1s that have been converted from Subnets as described in ACP-77. As such, `l1`/`L1` is generally preferred over `subnet`/`Subnet` in the source code. The one major exception is that `subnetID` should be used to refer to both Subnets that have not been converted, and L1s that have. This is because an L1 must first be initialized as a Subnet by issuing a `CreateSubnetTx` on the P-Chain, the transaction hash of which becomes the `subnetID`. Rather than change the name and/or value of this identifier, it is simpler for both to remain static in perpetuity. + +## Deploying + +The validator manager system consists of a `ValidatorManager`, and one of `NativeTokenStakingManager`, `ERC20TokenStakingManager`, or `PoAManager`. `ValidatorManager` is `Ownable`, and its owner should be set to the address of the other contract. + +All of these are implemented as [upgradeable](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/3d6a15108b50491ec3c51c03b32802c33e092a0f/contracts/proxy/utils/Initializable.sol#L56) contracts. There are numerous [guides](https://blog.chain.link/upgradable-smart-contracts/) for deploying upgradeable smart contracts, but the general steps are as follows: + +1. Deploy the implementation contract +2. Deploy the proxy contract +3. Call the implementation contract's `initialize` function + +- Each deployed contract requires different settings. For example, `ValidatorManagerSettings` specifies the churn parameters, while `StakingManagerSettings` specifies the staking and rewards parameters. + +4. Initialize the validator set by calling `initializeValidatorSet` on `ValidatorManager` + +- When an L1 is first created on the P-Chain, it must be explicitly converted to an L1 via [`ConvertSubnetToL1Tx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#convertsubnettol1tx). The resulting `SubnetToL1ConversionMessage` ICM [message](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#subnettol1conversionmessage) is provided in the call to `initializeValidatorSet` to specify the starting validator set in the `ValidatorManager`. Regardless of the setup of the overall validator manager system, these initial validators are treated as PoA and are not eligible for staking rewards. + +### Proof-of-Authority + +PoA validator management is provided by `PoAManager` by providing an `owner` in the call to `initialize`. Only the `owner` may initiate validator set changes, but anybody can complete the validator set change by providing the corresponding ICM message signed by the P-Chain. + +> [!NOTE] +> PoA validator management can also be implemented by `ValidatorManager` on its own, by setting the `owner` to the desired admin address. Unlike `PoAManager`, only the admin is able to initiate or complete validator set changes. + +### Proof-of-Stake + +PoS validator management is provided by the abstract contract `StakingManager`, which has two concrete implementations: `NativeTokenStakingManager` and `ERC20TokenStakingManager`. `StakingManager` supports uptime-based validation rewards, as well as delegation to a chosen validator. The `uptimeBlockchainID` used to initialize the `StakingManager` **must** be validated by the L1 validator set that the contract manages. **There is no way to verify this from within the contract, so take care when setting this value.** This [state transition diagram](./StateTransition.md) illustrates the relationship between validators and delegators. After deploying `StakingManager` and a proxy, call the `initialize` function, which takes a `StakingManagerSettings` as well as any implementation-specific arguments. + +> [!NOTE] +> The `weightToValueFactor` fields of `StakingManagerSettings` sets the factor used to convert between the weight that the validator is registered with on the P-Chain, and the value transferred to the contract as stake. This involves integer division, which may result in loss of precision. When selecting `weightToValueFactor`, it's important to make the following considerations: +> +> 1. If `weightToValueFactor` is near the denomination of the asset, then staking amounts on the order of 1 unit of the asset may cause the converted weight to round down to 0. This may impose a larger-than-expected minimum stake amount. +> - Ex: If USDC (denomination of 6) is used as the staking token and `weightToValueFactor` is 1e9, then any amount less than 1,000 USDC will round down to 0 and therefore be invalid. +> 2. Staked amounts up to `weightValueFactor - 1` may be lost in the contract as dust, as the validator's registered weight is used to calculate the original staked amount. +> - Ex: `value=1001` and `weightToValueFactor=1e3`. The resulting weight will be `1`. Converting the weight back to a value results in `value=1000`. +> 3. The validator's weight is represented on the P-Chain as a `uint64`. `StakingManager` restricts values such that the calculated weight does not exceed the maximum value for that type. + +### Migrating from Proof-of-Authority to Proof-of-Stake + +See the [migration guide](./PoAMigration.md) for details. + +#### NativeTokenStakingManager + +`NativeTokenStakingManager` allows permissionless addition and removal of validators that post the L1's native token as stake. Staking rewards are minted via the Native Minter Precompile, which is configured with a set of addresses with minting privileges. As such, the address that `NativeTokenStakingManager` is deployed to must be added as an admin to the precompile. This can be done by either calling the precompile's `setAdmin` method from an admin address, or setting the address in the Native Minter precompile settings in the chain's genesis (`config.contractNativeMinterConfig.adminAddresses`). There are a couple of methods to get this address: one is to calculate the resulting deployed address based on the deployer's address and account nonce: `keccak256(rlp.encode(address, nonce))`. The second method involves manually placing the `NativeTokenStakingManager` bytecode at a particular address in the genesis, then setting that address as an admin. + +```json +{ + "config" : { + ... + "contractNativeMinterConfig": { + "blockTimestamp": 0, + "adminAddresses": [ + "0xffffffffffffffffffffffffffffffffffffffff" + ] + } + }, + "alloc": { + "0xffffffffffffffffffffffffffffffffffffffff": { + "balance": "0x0", + "code": "", + "nonce": 1 + } + } +} +``` + +#### ERC20TokenStakingManager + +`ERC20TokenStakingManager` allows permissionless addition and removal of validators that post the an ERC20 token as stake. The ERC20 is specified in the call to `initialize`, and must implement [`IERC20Mintable`](./interfaces/IERC20Mintable.sol). Care should be taken to enforce that only authorized users are able to `mint` the ERC20 staking token. + +## Usage + + +### Register a Validator + +#### PoA + +Validator registration is initiated with a call to `PoAManager.initiateValidatorRegistration`. Churn limitations are checked - only a certain (configurable) percentage of the total weight is allowed to be added or removed in a (configurable) period of time. The `ValidatorManager` then constructs a [`RegisterL1ValidatorMessage`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#registerl1validatormessage) ICM message to be sent to the P-Chain. Each validator registration request includes all of the information needed to identify the validator and its stake weight, as well as an `expiry` timestamp before which the `RegisterL1ValidatorMessage` must be delivered to the P-Chain. If the validator is not registered on the P-Chain before the `expiry`, then the validator may be removed from the contract state by calling `completeValidatorRemoval`. + +The `RegisterL1ValidatorMessage` is delivered to the P-Chain as the ICM message payload of a `RegisterL1ValidatorTx`. Please see the transaction [specification](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#registerl1validatortx) for validity requirements. The P-Chain then signs a [`L1ValidatorRegistrationMessage`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#l1validatorregistrationmessage) ICM message indicating that the specified validator was successfully registered on the P-Chain. + +The `L1ValidatorRegistrationMessage` is delivered by calling `ValidatorManager.completeValidatorRegistration`. + +#### PoS + +When registering a PoS validator, the same steps as the PoA case apply, with the only difference being that `StakingManager.initiateValidatorRegistration` and `StakingManager.completeValidatorRegistration` must be called instead. + +The sender of the transaction that called `StakingManager.initiateValidatorRegistration` is registered as the validator owner. Only this owner can remove the validator. + +Staking rewards begin accruing once `StakingManager.completeValidatorRegistration` is called. + +### Remove a Validator + +### PoA + +Validator exit is initiated with a call to `PoAManager.initiateValidatorRemoval`. The `ValidatorManager` contructs an [`L1ValidatorWeightMessage`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#l1validatorweightmessage) ICM message with the weight set to `0`. This is delivered to the P-Chain as the payload of a [`SetL1ValidatorWeightTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#setl1validatorweighttx). The P-Chain acknowledges the validator exit by signing an `L1ValidatorRegistrationMessage` with `valid=0`, which is delivered by calling `ValidatorManager.completeValidatorRemoval`. The validation is removed from the contract's state. + +### PoS + +PoS validator removal follows the same flow as the PoA case, except that `StakingManager.initiateValidatorRemoval` and `StakingManager.completeValidatorRemoval` must be called instead. + +There are two additional considerations: + +- A [`ValidationUptimeMessage`](./UptimeMessageSpec.md) ICM message may optionally be provided in the call to `StakingManager.initiateValidatorRemoval` in order to calculate the staking rewards; otherwise the latest received uptime will be used (see [(PoS only) Submit and Uptime Proof](#pos-only-submit-an-uptime-proof)). This proof may be requested directly from the L1 validators, which will provide it in a `ValidationUptimeMessage` ICM message. If the uptime is not sufficient to earn validation rewards, the call to `initiateValidatorRemoval` will fail. `forceInitiateValidatorRemoval` acts the same as `initiateValidatorRemoval`, but bypasses the uptime-based rewards check. Once `initiateValidatorRemoval` or `forceInitiateValidatorRemoval` is called, staking rewards cease accruing for `StakingManagers`. + +- Unlike with PoA, PoS validators are not able to decrease their weight. This can lead to a scenario in which a PoS validator manager with a high proportion of the L1's weight is not able to exit the validator set due to churn restrictions. Additional validators or delegators will need to first be registered to more evenly distribute weight across the L1's validator set. + +Once acknowledgement from the P-Chain has been received via a call to `StakingManager.completeValidatorRemoval`, staking rewards are disbursed and stake is returned. + +#### Disable a Validator Directly on the P-Chain + +ACP-77 also provides a method to disable a validator without interacting with the L1 directly. The P-Chain transaction [`DisableL1ValidatorTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#disablel1validatortx) disables the validator on the P-Chain. The disabled validator's weight will still count towards the L1's total weight. + +Disabled L1 validators can re-activate at any time by increasing their balance with an `IncreaseBalanceTx`. Anyone can call `IncreaseBalanceTx` for any validator on the P-Chain. A disabled validator can only be completely and permanently removed from the validator set by a call to `initiateValidatorRemoval`. + +### (PoS only) Register a Delegator + +`StakingManager` supports delegation to an actively staked validator as a way for users to earn staking rewards without having to validate the chain. Delegators pay a configurable percentage fee on any earned staking rewards to the host validator. A delegator may be registered by calling `initiateDelegatorRegistration` and providing an amount to stake. The delegator will be registered as long as churn restrictions are not violated. The delegator is reflected on the P-Chain by adjusting the validator's registered weight via a [`SetL1ValidatorWeightTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#setl1validatorweighttx). The weight change acknowledgement is delivered to the `StakingManager` via an [`L1ValidatorWeightMessage`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#l1validatorweightmessage), which is provided by calling `completeDelegatorRegistration`. + +> [!NOTE] +> The P-Chain is only willing to sign an `L1ValidatorWeightMessage` for a validator in the L1's validator set. Once a validator exit has been initiated (via a call to `initiateValidatorRemoval`), the `StakingManager` must assume that the validator has been removed from the L1's validator set on the P-Chain, and therefore that the P-Chain will not sign any further weight updates. The contracts prohibit _initiating_ adding or removing a delegator in between calls to `initiateValidatorRemoval` and `completeValidatorRemoval`. However, if the `L1ValidatorWeightMessage` pertaining to an already initiated delegator action is constructed _before_ the validator is removed on the P-Chain, then the delegator action may be completed. Otherwise, `completeValidatorRemoval` must be called before completing the delegator action. + +### (PoS only) Remove a Delegator + +Delegator removal may be initiated by calling `initiateDelegatorRemoval`, as long as churn restrictions are not violated. Similar to `initiateValidatorRemoval`, an uptime proof may be provided to be used to determine delegator rewards eligibility. If no proof is provided, the latest known uptime will be used (see [(PoS only) Submit and Uptime Proof](#pos-only-submit-an-uptime-proof)). The validator's weight is updated on the P-Chain by the same mechanism used to register a delegator. The `L1ValidatorWeightMessage` from the P-Chain is delivered to the `StakingManager` in the call to `completeDelegatorRemoval`. + +Either the delegator owner or the validator owner may initiate removing a delegator. This is to prevent the validator from being unable to remove itself due to churn limitations if it is has too high a proportion of the Subnet's total weight due to delegator additions. The validator owner may only remove Delegators after the minimum stake duration has elapsed. + +### (PoS only) Submit an Uptime Proof + +The [rewards calculator](./interfaces/IRewardCalculator.sol) is a function of uptime seconds since the validator's start time. In addition to doing so in the calls to `initiateValidatorRemoval` and `initiateDelegatorRemoval` as described above, uptime proofs may also be supplied by calling `submitUptimeProof`. Unlike `initiateValidatorRemoval` and `initiateDelegatorRemoval`, `submitUptimeProof` may be called by anyone, decreasing the likelihood of a validation or delegation not being able to claim rewards that it deserved based on its actual uptime. + +### (PoS only) Collect Staking Rewards + +#### Validation Rewards + +Validation rewards are distributed in the call to `completeValidatorRemoval` on the `StakingManager`. + +#### Delegation Rewards + +Delegation rewards are distributed in the call to `completeDelegatorRemoval` on the `StakingManager`. + +#### Delegation Fees + +Delegation fees owed to validators are _not_ distributed when the validation ends as to bound the amount of gas consumed in the call to `completeValidatorRemoval`. Instead, `claimDelegationFees` on the `StakingManager` may be called after the validation is completed. diff --git a/icm-contracts/contracts/validator-manager/StakingManager.sol b/icm-contracts/contracts/validator-manager/StakingManager.sol new file mode 100644 index 000000000..67b0cecc6 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/StakingManager.sol @@ -0,0 +1,1060 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ValidatorMessages} from "./ValidatorMessages.sol"; +import {IValidatorManager} from "./interfaces/IValidatorManager.sol"; +import { + Delegator, + DelegatorStatus, + IStakingManager, + PoSValidatorInfo, + StakingManagerSettings +} from "./interfaces/IStakingManager.sol"; +import {Validator, ValidatorStatus, PChainOwner} from "./interfaces/IACP99Manager.sol"; +import {IRewardCalculator} from "./interfaces/IRewardCalculator.sol"; +import {IWarpMessenger, WarpMessage} from "@subnet-evm/IWarpMessenger.sol"; +import {ReentrancyGuardUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ReentrancyGuardUpgradeable.sol"; +import {ContextUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ContextUpgradeable.sol"; + +/** + * @dev Implementation of the {IStakingManager} interface. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +abstract contract StakingManager is + IStakingManager, + ContextUpgradeable, + ReentrancyGuardUpgradeable +{ + // solhint-disable private-vars-leading-underscore + /// @custom:storage-location erc7201:avalanche-icm.storage.StakingManager + struct StakingManagerStorage { + IValidatorManager _manager; + /// @notice The minimum amount of stake required to be a validator. + uint256 _minimumStakeAmount; + /// @notice The maximum amount of stake allowed to be a validator. + uint256 _maximumStakeAmount; + /// @notice The minimum amount of time in seconds a validator must be staked for. Must be at least {_churnPeriodSeconds}. + uint64 _minimumStakeDuration; + /// @notice The minimum delegation fee percentage, in basis points, required to delegate to a validator. + uint16 _minimumDelegationFeeBips; + /** + * @notice A multiplier applied to validator's initial stake amount to determine + * the maximum amount of stake a validator can have with delegations. + * Note: Setting this value to 1 would disable delegations to validators, since + * the maximum stake would be equal to the initial stake. + */ + uint64 _maximumStakeMultiplier; + /// @notice The factor used to convert between weight and value. + uint256 _weightToValueFactor; + /// @notice The reward calculator for this validator manager. + IRewardCalculator _rewardCalculator; + /// @notice The ID of the blockchain that submits uptime proofs. This must be a blockchain validated by the subnetID that this contract manages. + bytes32 _uptimeBlockchainID; + /// @notice Maps the validation ID to its requirements. + mapping(bytes32 validationID => PoSValidatorInfo) _posValidatorInfo; + /// @notice Maps the delegation ID to the delegator information. + mapping(bytes32 delegationID => Delegator) _delegatorStakes; + /// @notice Maps the delegation ID to its pending staking rewards. + mapping(bytes32 delegationID => uint256) _redeemableDelegatorRewards; + mapping(bytes32 delegationID => address) _delegatorRewardRecipients; + /// @notice Maps the validation ID to its pending staking rewards. + mapping(bytes32 validationID => uint256) _redeemableValidatorRewards; + /// @notice Maps the validation ID to its reward recipient. + mapping(bytes32 validationID => address) _rewardRecipients; + } + // solhint-enable private-vars-leading-underscore + + // keccak256(abi.encode(uint256(keccak256("avalanche-icm.storage.StakingManager")) - 1)) & ~bytes32(uint256(0xff)); + bytes32 public constant STAKING_MANAGER_STORAGE_LOCATION = + 0xafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab600; + + uint8 public constant MAXIMUM_STAKE_MULTIPLIER_LIMIT = 10; + + uint16 public constant MAXIMUM_DELEGATION_FEE_BIPS = 10000; + + uint16 public constant BIPS_CONVERSION_FACTOR = 10000; + + IWarpMessenger public constant WARP_MESSENGER = + IWarpMessenger(0x0200000000000000000000000000000000000005); + + error InvalidDelegationFee(uint16 delegationFeeBips); + error InvalidDelegationID(bytes32 delegationID); + error InvalidDelegatorStatus(DelegatorStatus status); + error InvalidRewardRecipient(address rewardRecipient); + error InvalidStakeAmount(uint256 stakeAmount); + error InvalidMinStakeDuration(uint64 minStakeDuration); + error InvalidStakeMultiplier(uint8 maximumStakeMultiplier); + error MaxWeightExceeded(uint64 newValidatorWeight); + error MinStakeDurationNotPassed(uint64 endTime); + error UnauthorizedOwner(address sender); + error ValidatorNotPoS(bytes32 validationID); + error ValidatorIneligibleForRewards(bytes32 validationID); + error DelegatorIneligibleForRewards(bytes32 delegationID); + error ZeroWeightToValueFactor(); + error InvalidUptimeBlockchainID(bytes32 uptimeBlockchainID); + + error InvalidWarpOriginSenderAddress(address senderAddress); + error InvalidWarpSourceChainID(bytes32 sourceChainID); + error UnexpectedValidationID(bytes32 validationID, bytes32 expectedValidationID); + error InvalidValidatorStatus(ValidatorStatus status); + error InvalidNonce(uint64 nonce); + error InvalidWarpMessage(); + error ZeroAddress(); + + // solhint-disable ordering + /** + * @dev This storage is visible to child contracts for convenience. + * External getters would be better practice, but code size limitations are preventing this. + * Child contracts should probably never write to this storage. + */ + function _getStakingManagerStorage() internal pure returns (StakingManagerStorage storage $) { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := STAKING_MANAGER_STORAGE_LOCATION + } + } + + // solhint-disable-next-line func-name-mixedcase + function __StakingManager_init( + StakingManagerSettings calldata settings + ) internal onlyInitializing { + __ReentrancyGuard_init(); + __StakingManager_init_unchained({ + manager: settings.manager, + minimumStakeAmount: settings.minimumStakeAmount, + maximumStakeAmount: settings.maximumStakeAmount, + minimumStakeDuration: settings.minimumStakeDuration, + minimumDelegationFeeBips: settings.minimumDelegationFeeBips, + maximumStakeMultiplier: settings.maximumStakeMultiplier, + weightToValueFactor: settings.weightToValueFactor, + rewardCalculator: settings.rewardCalculator, + uptimeBlockchainID: settings.uptimeBlockchainID + }); + } + + // solhint-disable-next-line func-name-mixedcase + function __StakingManager_init_unchained( + IValidatorManager manager, + uint256 minimumStakeAmount, + uint256 maximumStakeAmount, + uint64 minimumStakeDuration, + uint16 minimumDelegationFeeBips, + uint8 maximumStakeMultiplier, + uint256 weightToValueFactor, + IRewardCalculator rewardCalculator, + bytes32 uptimeBlockchainID + ) internal onlyInitializing { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + if (minimumDelegationFeeBips == 0 || minimumDelegationFeeBips > MAXIMUM_DELEGATION_FEE_BIPS) + { + revert InvalidDelegationFee(minimumDelegationFeeBips); + } + if (minimumStakeAmount > maximumStakeAmount) { + revert InvalidStakeAmount(minimumStakeAmount); + } + if (maximumStakeMultiplier == 0 || maximumStakeMultiplier > MAXIMUM_STAKE_MULTIPLIER_LIMIT) + { + revert InvalidStakeMultiplier(maximumStakeMultiplier); + } + if (address(manager) == address(0)) { + revert ZeroAddress(); + } + if (address(rewardCalculator) == address(0)) { + revert ZeroAddress(); + } + + // Minimum stake duration should be at least one churn period in order to prevent churn tracker abuse. + if (minimumStakeDuration < manager.getChurnPeriodSeconds()) { + revert InvalidMinStakeDuration(minimumStakeDuration); + } + if (weightToValueFactor == 0) { + revert ZeroWeightToValueFactor(); + } + if (uptimeBlockchainID == bytes32(0)) { + revert InvalidUptimeBlockchainID(uptimeBlockchainID); + } + + $._manager = manager; + $._minimumStakeAmount = minimumStakeAmount; + $._maximumStakeAmount = maximumStakeAmount; + $._minimumStakeDuration = minimumStakeDuration; + $._minimumDelegationFeeBips = minimumDelegationFeeBips; + $._maximumStakeMultiplier = maximumStakeMultiplier; + $._weightToValueFactor = weightToValueFactor; + $._rewardCalculator = rewardCalculator; + $._uptimeBlockchainID = uptimeBlockchainID; + } + + /** + * @notice See {IStakingManager-submitUptimeProof}. + */ + function submitUptimeProof(bytes32 validationID, uint32 messageIndex) external { + if (!_isPoSValidator(validationID)) { + revert ValidatorNotPoS(validationID); + } + ValidatorStatus status = + _getStakingManagerStorage()._manager.getValidator(validationID).status; + if (status != ValidatorStatus.Active) { + revert InvalidValidatorStatus(status); + } + + // Uptime proofs include the absolute number of seconds the validator has been active. + _updateUptime(validationID, messageIndex); + } + + /** + * @notice See {IStakingManager-claimDelegationFees}. + */ + function claimDelegationFees( + bytes32 validationID + ) external { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + ValidatorStatus status = $._manager.getValidator(validationID).status; + if (status != ValidatorStatus.Completed) { + revert InvalidValidatorStatus(status); + } + + if ($._posValidatorInfo[validationID].owner != _msgSender()) { + revert UnauthorizedOwner(_msgSender()); + } + + address rewardRecipient = $._rewardRecipients[validationID]; + + if (rewardRecipient == address(0)) { + rewardRecipient = $._posValidatorInfo[validationID].owner; + } + + _withdrawValidationRewards(rewardRecipient, validationID); + } + + /** + * @notice See {IStakingManager-initiateValidatorRemoval}. + */ + function initiateValidatorRemoval( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) external { + _initiateValidatorRemovalWithCheck(validationID, includeUptimeProof, messageIndex); + } + + function _initiateValidatorRemovalWithCheck( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) internal { + if (!_initiatePoSValidatorRemoval(validationID, includeUptimeProof, messageIndex)) { + revert ValidatorIneligibleForRewards(validationID); + } + } + + /** + * @notice See {IStakingManager-forceInitiateValidatorRemoval}. + */ + function forceInitiateValidatorRemoval( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) external { + // Ignore the return value here to force end validation, regardless of possible missed rewards + _initiatePoSValidatorRemoval(validationID, includeUptimeProof, messageIndex); + } + + /** + * @notice See {IStakingManager-changeValidatorRewardRecipient}. + */ + function changeValidatorRewardRecipient( + bytes32 validationID, + address rewardRecipient + ) external { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + if (rewardRecipient == address(0)) { + revert InvalidRewardRecipient(rewardRecipient); + } + + if ($._posValidatorInfo[validationID].owner != _msgSender()) { + revert UnauthorizedOwner(_msgSender()); + } + + address currentRecipient = $._rewardRecipients[validationID]; + $._rewardRecipients[validationID] = rewardRecipient; + + emit ValidatorRewardRecipientChanged(validationID, rewardRecipient, currentRecipient); + } + + /** + * @notice See {IStakingManager-changeDelegatorRewardRecipient}. + */ + function changeDelegatorRewardRecipient( + bytes32 delegationID, + address rewardRecipient + ) external { + if (rewardRecipient == address(0)) { + revert InvalidRewardRecipient(rewardRecipient); + } + + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + if ($._delegatorStakes[delegationID].owner != _msgSender()) { + revert UnauthorizedOwner(_msgSender()); + } + + address currentRecipient = $._delegatorRewardRecipients[delegationID]; + $._delegatorRewardRecipients[delegationID] = rewardRecipient; + + emit DelegatorRewardRecipientChanged(delegationID, rewardRecipient, currentRecipient); + } + + /** + * @dev Helper function that initiates the end of a PoS validation period. + * Returns false if it is possible for the validator to claim rewards, but it is not eligible. + * Returns true otherwise. + */ + function _initiatePoSValidatorRemoval( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) internal returns (bool) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + $._manager.initiateValidatorRemoval(validationID); + + // The validator must be fetched after the removal has been initiated, since the above call modifies + // the validator's state. + Validator memory validator = $._manager.getValidator(validationID); + + // Non-PoS validators are required to boostrap the network, but are not eligible for rewards. + if (!_isPoSValidator(validationID)) { + return true; + } + + // PoS validations can only be ended by their owners. + if ($._posValidatorInfo[validationID].owner != _msgSender()) { + revert UnauthorizedOwner(_msgSender()); + } + + // Check that minimum stake duration has passed. + if ( + validator.endTime + < validator.startTime + $._posValidatorInfo[validationID].minStakeDuration + ) { + revert MinStakeDurationNotPassed(validator.endTime); + } + + // Uptime proofs include the absolute number of seconds the validator has been active. + uint64 uptimeSeconds; + if (includeUptimeProof) { + uptimeSeconds = _updateUptime(validationID, messageIndex); + } else { + uptimeSeconds = $._posValidatorInfo[validationID].uptimeSeconds; + } + + uint256 reward = $._rewardCalculator.calculateReward({ + stakeAmount: weightToValue(validator.startingWeight), + validatorStartTime: validator.startTime, + stakingStartTime: validator.startTime, + stakingEndTime: validator.endTime, + uptimeSeconds: uptimeSeconds + }); + + $._redeemableValidatorRewards[validationID] += reward; + + return (reward > 0); + } + + /** + * @notice See {IStakingManager-completeValidatorRemoval}. + * Extends the functionality of {ACP99Manager-completeValidatorRemoval} by unlocking staking rewards. + */ + function completeValidatorRemoval( + uint32 messageIndex + ) external nonReentrant returns (bytes32) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + // Check if the validator has been already been removed from the validator manager. + bytes32 validationID = $._manager.completeValidatorRemoval(messageIndex); + Validator memory validator = $._manager.getValidator(validationID); + + // Return now if this was originally a PoA validator that was later migrated to this PoS manager, + // or the validator was part of the initial validator set. + if (!_isPoSValidator(validationID)) { + return validationID; + } + + address owner = $._posValidatorInfo[validationID].owner; + address rewardRecipient = $._rewardRecipients[validationID]; + + // the reward-recipient should always be set, but just in case it isn't, we won't burn the reward + if (rewardRecipient == address(0)) { + rewardRecipient = owner; + } + + // The validator can either be Completed or Invalidated here. We only grant rewards for Completed. + if (validator.status == ValidatorStatus.Completed) { + _withdrawValidationRewards(rewardRecipient, validationID); + } + + // The stake is unlocked whether the validation period is completed or invalidated. + _unlock(owner, weightToValue(validator.startingWeight)); + + return validationID; + } + + /** + * @dev Helper function that extracts the uptime from a ValidationUptimeMessage Warp message + * If the uptime is greater than the stored uptime, update the stored uptime. + */ + function _updateUptime(bytes32 validationID, uint32 messageIndex) internal returns (uint64) { + (WarpMessage memory warpMessage, bool valid) = + WARP_MESSENGER.getVerifiedWarpMessage(messageIndex); + if (!valid) { + revert InvalidWarpMessage(); + } + + StakingManagerStorage storage $ = _getStakingManagerStorage(); + // The uptime proof must be from the specifed uptime blockchain + if (warpMessage.sourceChainID != $._uptimeBlockchainID) { + revert InvalidWarpSourceChainID(warpMessage.sourceChainID); + } + + // The sender is required to be the zero address so that we know the validator node + // signed the proof directly, rather than as an arbitrary on-chain message + if (warpMessage.originSenderAddress != address(0)) { + revert InvalidWarpOriginSenderAddress(warpMessage.originSenderAddress); + } + + (bytes32 uptimeValidationID, uint64 uptime) = + ValidatorMessages.unpackValidationUptimeMessage(warpMessage.payload); + if (validationID != uptimeValidationID) { + revert UnexpectedValidationID(uptimeValidationID, validationID); + } + + if (uptime > $._posValidatorInfo[validationID].uptimeSeconds) { + $._posValidatorInfo[validationID].uptimeSeconds = uptime; + emit UptimeUpdated(validationID, uptime); + } else { + uptime = $._posValidatorInfo[validationID].uptimeSeconds; + } + + return uptime; + } + + /** + * @notice Initiates validator registration. Extends the functionality of {ACP99Manager-_initiateValidatorRegistration} + * by locking stake and setting staking and delegation parameters. + * @param delegationFeeBips The delegation fee in basis points. + * @param minStakeDuration The minimum stake duration in seconds. + * @param stakeAmount The amount of stake to lock. + */ + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount, + address rewardRecipient + ) internal virtual returns (bytes32) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + // Validate and save the validator requirements + if ( + delegationFeeBips < $._minimumDelegationFeeBips + || delegationFeeBips > MAXIMUM_DELEGATION_FEE_BIPS + ) { + revert InvalidDelegationFee(delegationFeeBips); + } + + if (minStakeDuration < $._minimumStakeDuration) { + revert InvalidMinStakeDuration(minStakeDuration); + } + + // Ensure the weight is within the valid range. + if (stakeAmount < $._minimumStakeAmount || stakeAmount > $._maximumStakeAmount) { + revert InvalidStakeAmount(stakeAmount); + } + + if (rewardRecipient == address(0)) { + revert InvalidRewardRecipient(rewardRecipient); + } + + // Lock the stake in the contract. + uint256 lockedValue = _lock(stakeAmount); + + uint64 weight = valueToWeight(lockedValue); + bytes32 validationID = $._manager.initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + weight: weight + }); + + address owner = _msgSender(); + + $._posValidatorInfo[validationID].owner = owner; + $._posValidatorInfo[validationID].delegationFeeBips = delegationFeeBips; + $._posValidatorInfo[validationID].minStakeDuration = minStakeDuration; + $._posValidatorInfo[validationID].uptimeSeconds = 0; + $._rewardRecipients[validationID] = rewardRecipient; + + emit InitiatedStakingValidatorRegistration( + validationID, owner, delegationFeeBips, minStakeDuration, rewardRecipient + ); + + return validationID; + } + + /** + * @notice See {IStakingManager-completeValidatorRegistration}. + */ + function completeValidatorRegistration( + uint32 messageIndex + ) external returns (bytes32) { + return _getStakingManagerStorage()._manager.completeValidatorRegistration(messageIndex); + } + + /** + * @notice Converts a token value to a weight. + * @param value Token value to convert. + */ + function valueToWeight( + uint256 value + ) public view returns (uint64) { + uint256 weight = value / _getStakingManagerStorage()._weightToValueFactor; + if (weight == 0 || weight > type(uint64).max) { + revert InvalidStakeAmount(value); + } + return uint64(weight); + } + + /** + * @notice Converts a weight to a token value. + * @param weight weight to convert. + */ + function weightToValue( + uint64 weight + ) public view returns (uint256) { + return uint256(weight) * _getStakingManagerStorage()._weightToValueFactor; + } + + /** + * @notice Returns the settings used to initialize the StakingManager + */ + function getStakingManagerSettings() public view returns (StakingManagerSettings memory) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + return StakingManagerSettings({ + manager: $._manager, + minimumStakeAmount: $._minimumStakeAmount, + maximumStakeAmount: $._maximumStakeAmount, + minimumStakeDuration: $._minimumStakeDuration, + minimumDelegationFeeBips: $._minimumDelegationFeeBips, + maximumStakeMultiplier: uint8($._maximumStakeMultiplier), + weightToValueFactor: $._weightToValueFactor, + rewardCalculator: $._rewardCalculator, + uptimeBlockchainID: $._uptimeBlockchainID + }); + } + + /** + * @notice Returns the PoS validator information for the given validationID + * See {ValidatorManager-getValidator} to retreive information about the validator not specific to PoS + */ + function getStakingValidator( + bytes32 validationID + ) public view returns (PoSValidatorInfo memory) { + return _getStakingManagerStorage()._posValidatorInfo[validationID]; + } + + /** + * @notice Returns the reward recipient and claimable reward amount for the given validationID + * @return The current validation reward recipient + * @return The current claimable validation reward amount + */ + function getValidatorRewardInfo( + bytes32 validationID + ) public view returns (address, uint256) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + return ($._rewardRecipients[validationID], $._redeemableValidatorRewards[validationID]); + } + + /** + * @notice Returns the delegator information for the given delegationID + */ + function getDelegatorInfo( + bytes32 delegationID + ) public view returns (Delegator memory) { + return _getStakingManagerStorage()._delegatorStakes[delegationID]; + } + + /** + * @notice Returns the reward recipient and claimable reward amount for the given delegationID + * @return The current delegation reward recipient + * @return The current claimable delegation reward amount + */ + function getDelegatorRewardInfo( + bytes32 delegationID + ) public view returns (address, uint256) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + return ( + $._delegatorRewardRecipients[delegationID], $._redeemableDelegatorRewards[delegationID] + ); + } + + /** + * @notice Locks tokens in this contract. + * @param value Number of tokens to lock. + */ + function _lock( + uint256 value + ) internal virtual returns (uint256); + + /** + * @notice Unlocks token to a specific address. + * @param to Address to send token to. + * @param value Number of tokens to lock. + */ + function _unlock(address to, uint256 value) internal virtual; + + /** + * @notice Initiates delegator registration by updating the validator's weight and storing the delegation information. + * Extends the functionality of {ACP99Manager-initiateValidatorWeightUpdate} by locking delegation stake. + * @param validationID The ID of the validator to delegate to. + * @param delegatorAddress The address of the delegator. + * @param delegationAmount The amount of stake to delegate. + * @param rewardRecipient The address of the reward recipient. + */ + function _initiateDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint256 delegationAmount, + address rewardRecipient + ) internal returns (bytes32) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + uint64 weight = valueToWeight(_lock(delegationAmount)); + + // Check that the validation ID is a PoS validator + if (!_isPoSValidator(validationID)) { + revert ValidatorNotPoS(validationID); + } + + if (rewardRecipient == address(0)) { + revert InvalidRewardRecipient(rewardRecipient); + } + + // Update the validator weight + uint64 newValidatorWeight; + { + Validator memory validator = $._manager.getValidator(validationID); + newValidatorWeight = validator.weight + weight; + if (newValidatorWeight > validator.startingWeight * $._maximumStakeMultiplier) { + revert MaxWeightExceeded(newValidatorWeight); + } + } + + (uint64 nonce, bytes32 messageID) = + $._manager.initiateValidatorWeightUpdate(validationID, newValidatorWeight); + + bytes32 delegationID = keccak256(abi.encodePacked(validationID, nonce)); + // Store the delegation information. Set the delegator status to pending added, + // so that it can be properly started in the complete step, even if the delivered + // nonce is greater than the nonce used to initiate registration. + $._delegatorStakes[delegationID].status = DelegatorStatus.PendingAdded; + $._delegatorStakes[delegationID].owner = delegatorAddress; + $._delegatorStakes[delegationID].validationID = validationID; + $._delegatorStakes[delegationID].weight = weight; + $._delegatorStakes[delegationID].startTime = 0; + $._delegatorStakes[delegationID].startingNonce = nonce; + $._delegatorStakes[delegationID].endingNonce = 0; + $._delegatorRewardRecipients[delegationID] = rewardRecipient; + + emit InitiatedDelegatorRegistration({ + delegationID: delegationID, + validationID: validationID, + delegatorAddress: delegatorAddress, + nonce: nonce, + validatorWeight: newValidatorWeight, + delegatorWeight: weight, + setWeightMessageID: messageID, + rewardRecipient: rewardRecipient + }); + return delegationID; + } + + /** + * @notice See {IStakingManager-completeDelegatorRegistration}. + * Extends the functionality of {ACP99Manager-completeValidatorWeightUpdate} by updating the delegation status. + */ + function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) external { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + Delegator memory delegator = $._delegatorStakes[delegationID]; + bytes32 validationID = delegator.validationID; + Validator memory validator = $._manager.getValidator(validationID); + + // Ensure the delegator is pending added. Since anybody can call this function once + // delegator registration has been initiated, we need to make sure that this function is only + // callable after that has been done. + if (delegator.status != DelegatorStatus.PendingAdded) { + revert InvalidDelegatorStatus(delegator.status); + } + + // In the case where the validator has completed its validation period, we can no + // longer stake and should move our status directly to completed and return the stake. + if (validator.status == ValidatorStatus.Completed) { + return _completeDelegatorRemoval(delegationID); + } + + // If we've already received a weight update with a nonce greater than the delegation's starting nonce, + // then there's no requirement to include an ICM message in this function call. + if (validator.receivedNonce < delegator.startingNonce) { + (bytes32 messageValidationID, uint64 nonce) = + $._manager.completeValidatorWeightUpdate(messageIndex); + + if (validationID != messageValidationID) { + revert UnexpectedValidationID(messageValidationID, validationID); + } + if (nonce < delegator.startingNonce) { + revert InvalidNonce(nonce); + } + } + + // Update the delegation status + $._delegatorStakes[delegationID].status = DelegatorStatus.Active; + $._delegatorStakes[delegationID].startTime = uint64(block.timestamp); + + emit CompletedDelegatorRegistration({ + delegationID: delegationID, + validationID: validationID, + startTime: uint64(block.timestamp) + }); + } + + /** + * @notice See {IStakingManager-initiateDelegatorRemoval}. + */ + function initiateDelegatorRemoval( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) external { + _initiateDelegatorRemovalWithCheck(delegationID, includeUptimeProof, messageIndex); + } + + function _initiateDelegatorRemovalWithCheck( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) internal { + if (!_initiateDelegatorRemoval(delegationID, includeUptimeProof, messageIndex)) { + revert DelegatorIneligibleForRewards(delegationID); + } + } + + /** + * @notice See {IStakingManager-forceInitiateDelegatorRemoval}. + */ + function forceInitiateDelegatorRemoval( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) external { + // Ignore the return value here to force end delegation, regardless of possible missed rewards + _initiateDelegatorRemoval(delegationID, includeUptimeProof, messageIndex); + } + + /** + * @dev Helper function that initiates the end of a PoS delegation period. + * Returns false if it is possible for the delegator to claim rewards, but it is not eligible. + * Returns true otherwise. + */ + function _initiateDelegatorRemoval( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) internal returns (bool) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + Delegator memory delegator = $._delegatorStakes[delegationID]; + bytes32 validationID = delegator.validationID; + Validator memory validator = $._manager.getValidator(validationID); + + // Ensure the delegator is active + if (delegator.status != DelegatorStatus.Active) { + revert InvalidDelegatorStatus(delegator.status); + } + + // Only the delegation owner or parent validator can end the delegation. + if (delegator.owner != _msgSender()) { + // Validators can only remove delegations after the minimum stake duration has passed. + if ($._posValidatorInfo[validationID].owner != _msgSender()) { + revert UnauthorizedOwner(_msgSender()); + } + + if ( + block.timestamp + < validator.startTime + $._posValidatorInfo[validationID].minStakeDuration + ) { + revert MinStakeDurationNotPassed(uint64(block.timestamp)); + } + } + + address rewardRecipient = $._delegatorRewardRecipients[delegationID]; + if (validator.status == ValidatorStatus.Active) { + // Check that minimum stake duration has passed. + if (block.timestamp < delegator.startTime + $._minimumStakeDuration) { + revert MinStakeDurationNotPassed(uint64(block.timestamp)); + } + + if (includeUptimeProof) { + // Uptime proofs include the absolute number of seconds the validator has been active. + _updateUptime(validationID, messageIndex); + } + + // Set the delegator status to pending removed, so that it can be properly removed in + // the complete step, even if the delivered nonce is greater than the nonce used to + // initiate the removal. + $._delegatorStakes[delegationID].status = DelegatorStatus.PendingRemoved; + + ($._delegatorStakes[delegationID].endingNonce,) = $ + ._manager + .initiateValidatorWeightUpdate(validationID, validator.weight - delegator.weight); + + uint256 reward = + _calculateAndSetDelegationReward(delegator, rewardRecipient, delegationID); + + emit InitiatedDelegatorRemoval({delegationID: delegationID, validationID: validationID}); + return (reward > 0); + } else if (validator.status == ValidatorStatus.Completed) { + _calculateAndSetDelegationReward(delegator, rewardRecipient, delegationID); + _completeDelegatorRemoval(delegationID); + // If the validator has completed, then no further uptimes may be submitted, so we always + // end the delegation. + return true; + } else { + revert InvalidValidatorStatus(validator.status); + } + } + + /** + * @dev Calculates the reward owed to the delegator based on the state of the delegator and its corresponding validator. + * then set the reward and reward recipient in the storage. + */ + function _calculateAndSetDelegationReward( + Delegator memory delegator, + address rewardRecipient, + bytes32 delegationID + ) private returns (uint256) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + Validator memory validator = $._manager.getValidator(delegator.validationID); + + uint64 delegationEndTime; + if ( + validator.status == ValidatorStatus.PendingRemoved + || validator.status == ValidatorStatus.Completed + ) { + delegationEndTime = validator.endTime; + } else if (validator.status == ValidatorStatus.Active) { + delegationEndTime = uint64(block.timestamp); + } else { + // Should be unreachable. + revert InvalidValidatorStatus(validator.status); + } + + // Only give rewards in the case that the delegation started before the validator exited. + if (delegationEndTime <= delegator.startTime) { + return 0; + } + + uint256 reward = $._rewardCalculator.calculateReward({ + stakeAmount: weightToValue(delegator.weight), + validatorStartTime: validator.startTime, + stakingStartTime: delegator.startTime, + stakingEndTime: delegationEndTime, + uptimeSeconds: $._posValidatorInfo[delegator.validationID].uptimeSeconds + }); + + if (rewardRecipient == address(0)) { + rewardRecipient = delegator.owner; + } + + $._redeemableDelegatorRewards[delegationID] = reward; + $._delegatorRewardRecipients[delegationID] = rewardRecipient; + + return reward; + } + + /** + * @notice See {IStakingManager-resendUpdateDelegator}. + * @dev Resending the latest validator weight with the latest nonce is safe because all weight changes are + * cumulative, so the latest weight change will always include the weight change for any added delegators. + */ + function resendUpdateDelegator( + bytes32 delegationID + ) external { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + Delegator memory delegator = $._delegatorStakes[delegationID]; + if ( + delegator.status != DelegatorStatus.PendingAdded + && delegator.status != DelegatorStatus.PendingRemoved + ) { + revert InvalidDelegatorStatus(delegator.status); + } + + Validator memory validator = $._manager.getValidator(delegator.validationID); + if (validator.sentNonce == 0) { + // Should be unreachable. + revert InvalidDelegationID(delegationID); + } + + // Submit the message to the Warp precompile. + WARP_MESSENGER.sendWarpMessage( + ValidatorMessages.packL1ValidatorWeightMessage( + delegator.validationID, validator.sentNonce, validator.weight + ) + ); + } + + /** + * @notice See {IStakingManager-completeDelegatorRemoval}. + * Extends the functionality of {ACP99Manager-completeValidatorWeightUpdate} by updating the delegation status and unlocking delegation rewards. + */ + function completeDelegatorRemoval( + bytes32 delegationID, + uint32 messageIndex + ) external nonReentrant { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + Delegator memory delegator = $._delegatorStakes[delegationID]; + + // Ensure the delegator is pending removed. Since anybody can call this function once + // end delegation has been initiated, we need to make sure that this function is only + // callable after that has been done. + if (delegator.status != DelegatorStatus.PendingRemoved) { + revert InvalidDelegatorStatus(delegator.status); + } + Validator memory validator = $._manager.getValidator(delegator.validationID); + + // We only expect an ICM message if we haven't received a weight update with a nonce greater than the delegation's ending nonce + if ( + $._manager.getValidator(delegator.validationID).status != ValidatorStatus.Completed + && validator.receivedNonce < delegator.endingNonce + ) { + (bytes32 validationID, uint64 nonce) = + $._manager.completeValidatorWeightUpdate(messageIndex); + if (delegator.validationID != validationID) { + revert UnexpectedValidationID(validationID, delegator.validationID); + } + + // The received nonce should be at least as high as the delegation's ending nonce. This allows a weight + // update using a higher nonce (which implicitly includes the delegation's weight update) to be used to + // complete delisting for an earlier delegation. This is necessary because the P-Chain is only willing + // to sign the latest weight update. + if (delegator.endingNonce > nonce) { + revert InvalidNonce(nonce); + } + } + + _completeDelegatorRemoval(delegationID); + } + + function _completeDelegatorRemoval( + bytes32 delegationID + ) internal { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + Delegator memory delegator = $._delegatorStakes[delegationID]; + bytes32 validationID = delegator.validationID; + + // To prevent churn tracker abuse, check that one full churn period has passed, + // so a delegator may not stake twice in the same churn period. + if (block.timestamp < delegator.startTime + $._manager.getChurnPeriodSeconds()) { + revert MinStakeDurationNotPassed(uint64(block.timestamp)); + } + + // Once this function completes, the delegation is completed so we can clear it from state now. + delete $._delegatorStakes[delegationID]; + + address rewardRecipient = $._delegatorRewardRecipients[delegationID]; + delete $._delegatorRewardRecipients[delegationID]; + + if (rewardRecipient == address(0)) { + rewardRecipient = delegator.owner; + } + + (uint256 delegationRewards, uint256 validatorFees) = + _withdrawDelegationRewards(rewardRecipient, delegationID, validationID); + + // Unlock the delegator's stake. + _unlock(delegator.owner, weightToValue(delegator.weight)); + + emit CompletedDelegatorRemoval(delegationID, validationID, delegationRewards, validatorFees); + } + + /** + * @dev This function must be implemented to mint rewards to validators and delegators. + */ + function _reward(address account, uint256 amount) internal virtual; + + /** + * @dev Return true if this is a PoS validator with locked stake. Returns false if this was originally a PoA + * validator that was later migrated to this PoS manager, or the validator was part of the initial validator set. + */ + function _isPoSValidator( + bytes32 validationID + ) internal view returns (bool) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + return $._posValidatorInfo[validationID].owner != address(0); + } + + function _withdrawValidationRewards(address rewardRecipient, bytes32 validationID) internal { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + uint256 rewards = $._redeemableValidatorRewards[validationID]; + delete $._redeemableValidatorRewards[validationID]; + + _reward(rewardRecipient, rewards); + + emit ValidatorRewardClaimed(validationID, rewardRecipient, rewards); + } + + function _withdrawDelegationRewards( + address rewardRecipient, + bytes32 delegationID, + bytes32 validationID + ) internal returns (uint256, uint256) { + StakingManagerStorage storage $ = _getStakingManagerStorage(); + + uint256 delegationRewards; + uint256 validatorFees; + + uint256 rewards = $._redeemableDelegatorRewards[delegationID]; + + if (rewards > 0) { + delete $._redeemableDelegatorRewards[delegationID]; + + validatorFees = (rewards * $._posValidatorInfo[validationID].delegationFeeBips) + / BIPS_CONVERSION_FACTOR; + + // Allocate the delegation fees to the validator. + $._redeemableValidatorRewards[validationID] += validatorFees; + + // Reward the remaining tokens to the delegator. + delegationRewards = rewards - validatorFees; + _reward(rewardRecipient, delegationRewards); + + emit DelegatorRewardClaimed(delegationID, rewardRecipient, delegationRewards); + } + + return (delegationRewards, validatorFees); + } +} diff --git a/icm-contracts/contracts/validator-manager/StateTransition.md b/icm-contracts/contracts/validator-manager/StateTransition.md new file mode 100644 index 000000000..719ad9f1a --- /dev/null +++ b/icm-contracts/contracts/validator-manager/StateTransition.md @@ -0,0 +1,34 @@ +## State Transitions + +The following state transition diagram illustrates the relationship between validator and delegator state. `Validator` is abbreviated as `V`, `Delegator` is abbreviated as `D`, and function names are shortened to improve readability. `Delegator.Completed` is omitted to show equivalance between the validator's initial state and the state after a delegation completes. + +```mermaid +stateDiagram-v2 + % Happy path + [*] --> V.PendingAdded : initVdrReg + V.PendingAdded --> V.Active : completeVdrReg + V.PendingAdded --> V.Completed : completeVdrReg (expiry passed) + V.Active --> V.Active,D.PendingAdded : initDelReg + V.Active,D.PendingAdded --> V.Active,D.Active : completeDelReg + V.Active,D.Active --> V.Active,D.PendingRemoved : initEndDel + V.Active,D.PendingRemoved --> V.Active : completeEndDel + V.Active --> V.PendingRemoved : initEndVdr + V.PendingRemoved --> V.Completed : completeEndVdr + + % Validator/Delegator state changes do not affect the Delegator/Validator state + V.Active,D.PendingRemoved --> V.PendingRemoved,D.PendingRemoved : initEndVdr + V.Active,D.PendingAdded --> V.PendingRemoved,D.PendingAdded : initEndVdr + V.Active,D.Active --> V.PendingRemoved,D.Active: initEndVdr + + % When the Validator is in PendingRemoved or Completed, in general Delegator actions + % may be completed, but not initiated. + V.PendingRemoved,D.PendingAdded --> V.Completed,D.PendingAdded : completeEndVdr + V.PendingRemoved,D.PendingRemoved --> V.Completed,D.PendingRemoved : completeEndVdr + V.PendingRemoved,D.PendingRemoved --> V.PendingRemoved : completeEndDel + V.PendingRemoved,D.Active --> V.Completed,D.Active : completeEndVdr + % This is a no-op + V.PendingRemoved,D.PendingAdded --> V.PendingRemoved,D.Active : completeDelReg + V.Completed,D.PendingRemoved --> V.Completed : completeEndDel + V.Completed,D.Active --> V.Completed : initEndDel + V.Completed,D.PendingAdded --> V.Completed : completeDelReg +``` diff --git a/icm-contracts/contracts/validator-manager/UptimeMessageSpec.md b/icm-contracts/contracts/validator-manager/UptimeMessageSpec.md new file mode 100644 index 000000000..e9635c4cd --- /dev/null +++ b/icm-contracts/contracts/validator-manager/UptimeMessageSpec.md @@ -0,0 +1,19 @@ +# `ValidationUptimeMessage` Warp Message Format Reference + +Description: Provides a validator's uptime for calculating staking rewards (`StakingManager` only) + +Signed by: L1 + +Consumed by: Validator Manager Contract + +Specification: + +| Field | Type | Size | +| -------------: | ---------: | -------: | +| `codecID` | `uint16` | 2 bytes | +| `typeID` | `uint32` | 4 bytes | +| `validationID` | `[32]byte` | 32 bytes | +| `uptime` | `uint64` | 8 byte | +| | | 46 bytes | + +This is defined within `Subnet-EVM` [here](https://github.com/ava-labs/subnet-evm/blob/323eb0c7dd7204521e662a3a355fe78a0e19c0be/warp/messages/validator_uptime.go#L14-L19). The `ValidationUptimeMessage` must be included as an `AddressedPayload` with the `sourceAddress` set to an empty byte array, to prove that it did not originate as an arbitrary on-chain message. The `sourceChainID` must match the `uptimeBlockchainID` used to initialize the `StakingManager`. `uptimeBlockchainID` must be validated by the L1 validator set managed by the `StakingManager`. \ No newline at end of file diff --git a/icm-contracts/contracts/validator-manager/ValidatorManager.sol b/icm-contracts/contracts/validator-manager/ValidatorManager.sol new file mode 100644 index 000000000..424bd8d33 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/ValidatorManager.sol @@ -0,0 +1,780 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IValidatorManager} from "./interfaces/IValidatorManager.sol"; +import {ValidatorMessages} from "./ValidatorMessages.sol"; +import { + InitialValidator, + PChainOwner, + ConversionData, + Validator, + ValidatorStatus +} from "./interfaces/IACP99Manager.sol"; +import {ACP99Manager} from "./ACP99Manager.sol"; +import {IWarpMessenger, WarpMessage} from "@subnet-evm/IWarpMessenger.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; + +/** + * @dev Describes the current churn period + */ +struct ValidatorChurnPeriod { + uint256 startTime; + uint64 initialWeight; + uint64 totalWeight; + uint64 churnAmount; +} + +/** + * @notice Validator Manager settings, used to initialize the Validator Manager + * @param The subnetID is the ID of the L1 that the Validator Manager is managing + * @param The churnPeriodSeconds is the duration of the churn period in seconds + * @param The maximumChurnPercentage is the maximum percentage of the total weight that can be added or removed in a single churn period + */ +struct ValidatorManagerSettings { + address admin; + bytes32 subnetID; + uint64 churnPeriodSeconds; + uint8 maximumChurnPercentage; +} + +/// @dev Legacy struct used to migrate from V1 contracts +struct ValidatorLegacy { + ValidatorStatus status; + bytes nodeID; + uint64 startingWeight; + uint64 messageNonce; + uint64 weight; + uint64 startedAt; + uint64 endedAt; +} + +/** + * @dev Implementation of the {ACP99Manager} abstract contract. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +contract ValidatorManager is IValidatorManager, Initializable, OwnableUpgradeable, ACP99Manager { + // solhint-disable private-vars-leading-underscore + /// @custom:storage-location erc7201:avalanche-icm.storage.ValidatorManager + struct ValidatorManagerStorage { + /// @notice The subnetID associated with this validator manager. + bytes32 _subnetID; + /// @notice The number of seconds after which to reset the churn tracker. + uint64 _churnPeriodSeconds; + /// @notice The maximum churn rate allowed per churn period. + uint8 _maximumChurnPercentage; + /// @notice The churn tracker used to track the amount of stake added or removed in the churn period. + ValidatorChurnPeriod _churnTracker; + /// @notice Maps the validationID to the registration message such that the message can be re-sent if needed. + mapping(bytes32 => bytes) _pendingRegisterValidationMessages; + /// @notice Legacy storage for V1 validators. + mapping(bytes32 => ValidatorLegacy) _validationPeriodsLegacy; + /// @notice Maps the nodeID to the validationID for validation periods that have not ended. + mapping(bytes => bytes32) _registeredValidators; + /// @notice Boolean that indicates if the initial validator set has been set. + bool _initializedValidatorSet; + /// @notice Maps the validationID to the validator information. + mapping(bytes32 => Validator) _validationPeriods; + } + // solhint-enable private-vars-leading-underscore + + // keccak256(abi.encode(uint256(keccak256("avalanche-icm.storage.ValidatorManager")) - 1)) & ~bytes32(uint256(0xff)); + bytes32 public constant VALIDATOR_MANAGER_STORAGE_LOCATION = + 0xe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb00; + + uint64 public constant REGISTRATION_EXPIRY_LENGTH = 1 days; + // Limit churn period to the registration expiry length, so that a validation can only + // be represented once per churn period + uint64 public constant MAXIMUM_CHURN_PERIOD_LENGTH = REGISTRATION_EXPIRY_LENGTH; + uint8 public constant MAXIMUM_CHURN_PERCENTAGE_LIMIT = 20; + uint32 public constant NODE_ID_LENGTH = 20; + uint8 public constant BLS_PUBLIC_KEY_LENGTH = 48; + bytes32 public constant P_CHAIN_BLOCKCHAIN_ID = bytes32(0); + + // solhint-disable ordering + /** + * @dev This storage is visible to child contracts for convenience. + * External getters would be better practice, but code size limitations are preventing this. + * Child contracts should probably never write to this storage. + */ + function _getValidatorManagerStorage() + internal + pure + returns (ValidatorManagerStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := VALIDATOR_MANAGER_STORAGE_LOCATION + } + } + + /** + * @notice Warp precompile used for sending and receiving Warp messages. + */ + IWarpMessenger public constant WARP_MESSENGER = + IWarpMessenger(0x0200000000000000000000000000000000000005); + + constructor( + ICMInitializable init + ) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Migrates a validator from the V1 contract to the V2 contract. + * @param validationID The ID of the validation period to migrate. + * @param receivedNonce The latest nonce received from the P-Chain. + */ + function migrateFromV1(bytes32 validationID, uint32 receivedNonce) external { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + ValidatorLegacy storage legacy = $._validationPeriodsLegacy[validationID]; + if (legacy.status == ValidatorStatus.Unknown) { + revert InvalidValidationID(validationID); + } + if (receivedNonce > legacy.messageNonce) { + revert InvalidNonce(receivedNonce); + } + + $._validationPeriods[validationID] = Validator({ + status: legacy.status, + nodeID: legacy.nodeID, + startingWeight: legacy.startingWeight, + sentNonce: legacy.messageNonce, + receivedNonce: receivedNonce, + weight: legacy.weight, + startTime: legacy.startedAt, + endTime: legacy.endedAt + }); + + // Set the legacy status to unknown to disallow future migrations. + $._validationPeriodsLegacy[validationID].status = ValidatorStatus.Unknown; + } + + function initialize( + ValidatorManagerSettings calldata settings + ) external initializer { + __ValidatorManager_init(settings); + } + + // solhint-disable-next-line func-name-mixedcase + function __ValidatorManager_init( + ValidatorManagerSettings calldata settings + ) internal onlyInitializing { + __Ownable_init(settings.admin); + __ValidatorManager_init_unchained(settings); + } + + // solhint-disable-next-line func-name-mixedcase + function __ValidatorManager_init_unchained( + ValidatorManagerSettings calldata settings + ) internal onlyInitializing { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + $._subnetID = settings.subnetID; + + if ( + settings.maximumChurnPercentage > MAXIMUM_CHURN_PERCENTAGE_LIMIT + || settings.maximumChurnPercentage == 0 + ) { + revert InvalidMaximumChurnPercentage(settings.maximumChurnPercentage); + } + if (settings.churnPeriodSeconds > MAXIMUM_CHURN_PERIOD_LENGTH) { + revert InvalidChurnPeriodLength(settings.churnPeriodSeconds); + } + + $._maximumChurnPercentage = settings.maximumChurnPercentage; + $._churnPeriodSeconds = settings.churnPeriodSeconds; + } + + modifier initializedValidatorSet() { + if (!_getValidatorManagerStorage()._initializedValidatorSet) { + revert InvalidInitializationStatus(); + } + _; + } + + /** + * @notice See {IACP99Manager-initializeValidatorSet}. + */ + function initializeValidatorSet( + ConversionData calldata conversionData, + uint32 messageIndex + ) public virtual override { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + if ($._initializedValidatorSet) { + revert InvalidInitializationStatus(); + } + + // Check that the blockchainID and validator manager address in the ConversionData correspond to this contract. + // Other validation checks are done by the P-Chain when converting the L1, so are not required here. + if (conversionData.validatorManagerBlockchainID != WARP_MESSENGER.getBlockchainID()) { + revert InvalidValidatorManagerBlockchainID(conversionData.validatorManagerBlockchainID); + } + if (address(conversionData.validatorManagerAddress) != address(this)) { + revert InvalidValidatorManagerAddress(address(conversionData.validatorManagerAddress)); + } + + // Verify that the sha256 hash of the L1 conversion data matches with the Warp message's conversionID. + bytes32 conversionID = ValidatorMessages.unpackSubnetToL1ConversionMessage( + _getPChainWarpMessage(messageIndex).payload + ); + bytes memory encodedConversion = ValidatorMessages.packConversionData(conversionData); + bytes32 encodedConversionID = sha256(encodedConversion); + if (encodedConversionID != conversionID) { + revert InvalidConversionID(encodedConversionID, conversionID); + } + + uint256 numInitialValidators = conversionData.initialValidators.length; + + uint64 totalWeight; + for (uint32 i; i < numInitialValidators; ++i) { + InitialValidator memory initialValidator = conversionData.initialValidators[i]; + if ($._registeredValidators[initialValidator.nodeID] != bytes32(0)) { + revert NodeAlreadyRegistered(initialValidator.nodeID); + } + if (initialValidator.nodeID.length != NODE_ID_LENGTH) { + revert InvalidNodeID(initialValidator.nodeID); + } + + // Validation ID of the initial validators is the sha256 hash of the + // subnet ID and the index of the initial validator. + bytes32 validationID = sha256(abi.encodePacked(conversionData.subnetID, i)); + + // Save the initial validator as an active validator. + $._registeredValidators[initialValidator.nodeID] = validationID; + $._validationPeriods[validationID].status = ValidatorStatus.Active; + $._validationPeriods[validationID].nodeID = initialValidator.nodeID; + $._validationPeriods[validationID].startingWeight = initialValidator.weight; + $._validationPeriods[validationID].sentNonce = 0; + $._validationPeriods[validationID].weight = initialValidator.weight; + $._validationPeriods[validationID].startTime = uint64(block.timestamp); + $._validationPeriods[validationID].endTime = 0; + totalWeight += initialValidator.weight; + + emit RegisteredInitialValidator( + validationID, + _fixedNodeID(initialValidator.nodeID), + conversionData.subnetID, + initialValidator.weight + ); + } + $._churnTracker.totalWeight = totalWeight; + + // Rearranged equation for totalWeight < (100 / $._maximumChurnPercentage) + // Total weight must be above this value in order to not trigger churn limits with an added/removed weight of 1. + if (totalWeight * $._maximumChurnPercentage < 100) { + revert InvalidTotalWeight(totalWeight); + } + + $._initializedValidatorSet = true; + } + + function _validatePChainOwner( + PChainOwner memory pChainOwner + ) internal pure { + // If threshold is 0, addresses must be empty. + if (pChainOwner.threshold == 0 && pChainOwner.addresses.length != 0) { + revert InvalidPChainOwnerThreshold(pChainOwner.threshold, pChainOwner.addresses.length); + } + // Threshold must be less than or equal to the number of addresses. + if (pChainOwner.threshold > pChainOwner.addresses.length) { + revert InvalidPChainOwnerThreshold(pChainOwner.threshold, pChainOwner.addresses.length); + } + // Zero address is invalid. Because we require addresses to be sorted, we only need to check if the first is 0 + if (pChainOwner.addresses.length > 0 && pChainOwner.addresses[0] == address(0)) { + revert ZeroAddress(); + } + // Addresses must be unique and sorted in ascending order + for (uint256 i = 1; i < pChainOwner.addresses.length; i++) { + // Compare current address with the previous one + if (pChainOwner.addresses[i] <= pChainOwner.addresses[i - 1]) { + revert InvalidPChainOwnerAddresses(); + } + } + } + + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) public onlyOwner returns (bytes32) { + return _initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + weight: weight + }); + } + + /** + * @notice See {ACP99Manager-_initiateValidatorRegistration}. + * @dev This function modifies the validator's state. Callers should ensure that any references are updated. + */ + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) internal virtual override initializedValidatorSet returns (bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + // Ensure the new validator doesn't overflow the total weight + if (uint256(weight) + uint256($._churnTracker.totalWeight) > type(uint64).max) { + revert InvalidTotalWeight(weight); + } + + _validatePChainOwner(remainingBalanceOwner); + _validatePChainOwner(disableOwner); + + // Ensure the nodeID is not the zero address, and is not already an active validator. + + if (blsPublicKey.length != BLS_PUBLIC_KEY_LENGTH) { + revert InvalidBLSKeyLength(blsPublicKey.length); + } + if (nodeID.length != NODE_ID_LENGTH) { + revert InvalidNodeID(nodeID); + } + if ($._registeredValidators[nodeID] != bytes32(0)) { + revert NodeAlreadyRegistered(nodeID); + } + + // Check that adding this validator would not exceed the maximum churn rate. + _checkAndUpdateChurnTracker(weight, 0); + + uint64 registrationExpiry = uint64(block.timestamp) + REGISTRATION_EXPIRY_LENGTH; + + (bytes32 validationID, bytes memory registerL1ValidatorMessage) = ValidatorMessages + .packRegisterL1ValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: $._subnetID, + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + registrationExpiry: registrationExpiry, + weight: weight + }) + ); + + // Redundant check to ensure no collision or replay is possible, but with the expiry set as + // the block timestamp + 1 day, this should not be possible. + if ($._validationPeriods[validationID].status != ValidatorStatus.Unknown) { + revert InvalidValidatorStatus($._validationPeriods[validationID].status); + } + + $._pendingRegisterValidationMessages[validationID] = registerL1ValidatorMessage; + $._registeredValidators[nodeID] = validationID; + + // Submit the message to the Warp precompile. + bytes32 messageID = WARP_MESSENGER.sendWarpMessage(registerL1ValidatorMessage); + $._validationPeriods[validationID].status = ValidatorStatus.PendingAdded; + $._validationPeriods[validationID].nodeID = nodeID; + $._validationPeriods[validationID].startingWeight = weight; + $._validationPeriods[validationID].sentNonce = 0; + $._validationPeriods[validationID].weight = weight; + $._validationPeriods[validationID].startTime = 0; // The validation period only starts once the registration is acknowledged. + $._validationPeriods[validationID].endTime = 0; + + emit InitiatedValidatorRegistration( + validationID, _fixedNodeID(nodeID), messageID, registrationExpiry, weight + ); + + return validationID; + } + + /** + * @notice Resubmits a validator registration message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param validationID The ID of the validation period being registered. + */ + function resendRegisterValidatorMessage( + bytes32 validationID + ) external { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + // The initial validator set must have been set already to have pending register validation messages. + if ($._pendingRegisterValidationMessages[validationID].length == 0) { + revert InvalidValidationID(validationID); + } + if ($._validationPeriods[validationID].status != ValidatorStatus.PendingAdded) { + revert InvalidValidatorStatus($._validationPeriods[validationID].status); + } + + // Submit the message to the Warp precompile. + WARP_MESSENGER.sendWarpMessage($._pendingRegisterValidationMessages[validationID]); + } + + /** + * @notice See {IACP99Manager-completeValidatorRegistration}. + */ + function completeValidatorRegistration( + uint32 messageIndex + ) public virtual override onlyOwner returns (bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + (bytes32 validationID, bool validRegistration) = ValidatorMessages + .unpackL1ValidatorRegistrationMessage(_getPChainWarpMessage(messageIndex).payload); + + if (!validRegistration) { + revert UnexpectedRegistrationStatus(validRegistration); + } + // The initial validator set must have been set already to have pending register validation messages. + if ($._pendingRegisterValidationMessages[validationID].length == 0) { + revert InvalidValidationID(validationID); + } + if ($._validationPeriods[validationID].status != ValidatorStatus.PendingAdded) { + revert InvalidValidatorStatus($._validationPeriods[validationID].status); + } + + delete $._pendingRegisterValidationMessages[validationID]; + $._validationPeriods[validationID].status = ValidatorStatus.Active; + $._validationPeriods[validationID].startTime = uint64(block.timestamp); + emit CompletedValidatorRegistration(validationID, $._validationPeriods[validationID].weight); + + return validationID; + } + + /** + * @notice See {IACP99Manager-getValidator}. + */ + function getValidator( + bytes32 validationID + ) public view virtual override returns (Validator memory) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return $._validationPeriods[validationID]; + } + + /** + * @notice See {IACP99Manager-l1TotalWeight}. + */ + function l1TotalWeight() public view virtual override returns (uint64) { + return _getValidatorManagerStorage()._churnTracker.totalWeight; + } + + /** + * @notice See {IACP99Manager-subnetID}. + */ + function subnetID() public view virtual override returns (bytes32) { + return _getValidatorManagerStorage()._subnetID; + } + + /** + * @notice Returns the current churn tracker and its configuration + * @return The churn period duration in seconds + * @return The maximum percentage of total L1 weight churn allowed per period + * @return The current churn tracker + */ + function getChurnTracker() public view returns (uint64, uint8, ValidatorChurnPeriod memory) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return ($._churnPeriodSeconds, $._maximumChurnPercentage, $._churnTracker); + } + + /** + * @notice Returns the validationID that the provided nodeID is registered under + * @param nodeID ID of the node associated with the validation ID + */ + function getNodeValidationID( + bytes calldata nodeID + ) public view returns (bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return $._registeredValidators[nodeID]; + } + + /** + * @notice Returns true if the ValidatorManager has been initialized with the initial validator set + */ + function isValidatorSetInitialized() public view returns (bool) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return $._initializedValidatorSet; + } + + /** + * @notice Initiates the removal of a validator from the active validator set. + */ + function initiateValidatorRemoval( + bytes32 validationID + ) public onlyOwner { + _initiateValidatorRemoval(validationID); + } + + /** + * @notice See {ACP99Manager-_initiateValidatorRemoval}. + * @dev This function modifies the validator's state. Callers should ensure that any references are updated. + */ + function _initiateValidatorRemoval( + bytes32 validationID + ) internal virtual override { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + // Ensure the validation period is active. + // The initial validator set must have been set already to have active validators. + Validator memory validator = $._validationPeriods[validationID]; + if (validator.status != ValidatorStatus.Active) { + revert InvalidValidatorStatus($._validationPeriods[validationID].status); + } + + // Update the validator status to pending removal. + // They are not removed from the active validators mapping until the P-Chain acknowledges the removal. + validator.status = ValidatorStatus.PendingRemoved; + + // Set the end time of the validation period, since it is no longer known to be an active validator + // on the P-Chain. + validator.endTime = uint64(block.timestamp); + + // Save the validator updates. + $._validationPeriods[validationID] = validator; + + (, bytes32 messageID) = _initiateValidatorWeightUpdate(validationID, 0); + + // Emit the event to signal the start of the validator removal process. + emit InitiatedValidatorRemoval( + validationID, messageID, validator.weight, uint64(block.timestamp) + ); + } + + /** + * @notice Resubmits a validator end message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param validationID The ID of the validation period being ended. + */ + function resendValidatorRemovalMessage( + bytes32 validationID + ) external { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + Validator memory validator = $._validationPeriods[validationID]; + + // The initial validator set must have been set already to have pending end validation messages. + if (validator.status != ValidatorStatus.PendingRemoved) { + revert InvalidValidatorStatus($._validationPeriods[validationID].status); + } + + WARP_MESSENGER.sendWarpMessage( + ValidatorMessages.packL1ValidatorWeightMessage(validationID, validator.sentNonce, 0) + ); + } + + /** + * @notice See {IACP99Manager-completeValidatorRemoval}. + */ + function completeValidatorRemoval( + uint32 messageIndex + ) public virtual override onlyOwner returns (bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + // Get the Warp message. + (bytes32 validationID, bool registered) = ValidatorMessages + .unpackL1ValidatorRegistrationMessage(_getPChainWarpMessage(messageIndex).payload); + if (registered) { + revert UnexpectedRegistrationStatus(registered); + } + + Validator memory validator = $._validationPeriods[validationID]; + + // The validation status is PendingRemoved if validator removal was initiated with a call to {initiateValidatorRemoval}. + // The validation status is PendingAdded if the validator was never registered on the P-Chain. + // The initial validator set must have been set already to have pending validation messages. + if ( + validator.status != ValidatorStatus.PendingRemoved + && validator.status != ValidatorStatus.PendingAdded + ) { + revert InvalidValidatorStatus(validator.status); + } + + if (validator.status == ValidatorStatus.PendingRemoved) { + validator.status = ValidatorStatus.Completed; + } else { + // Remove the validator's weight from the total tracked weight, but don't track it as churn. + $._churnTracker.totalWeight -= validator.weight; + validator.status = ValidatorStatus.Invalidated; + } + // Remove the validator from the registered validators mapping. + delete $._registeredValidators[validator.nodeID]; + + // Update the validator. + $._validationPeriods[validationID] = validator; + + // Emit event. + emit CompletedValidatorRemoval(validationID); + + return validationID; + } + + function _incrementSentNonce( + bytes32 validationID + ) internal returns (uint64) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return ++$._validationPeriods[validationID].sentNonce; + } + + function _getPChainWarpMessage( + uint32 messageIndex + ) internal view returns (WarpMessage memory) { + (WarpMessage memory warpMessage, bool valid) = + WARP_MESSENGER.getVerifiedWarpMessage(messageIndex); + if (!valid) { + revert InvalidWarpMessage(); + } + // Must match to P-Chain blockchain id, which is 0. + if (warpMessage.sourceChainID != P_CHAIN_BLOCKCHAIN_ID) { + revert InvalidWarpSourceChainID(warpMessage.sourceChainID); + } + if (warpMessage.originSenderAddress != address(0)) { + revert InvalidWarpOriginSenderAddress(warpMessage.originSenderAddress); + } + + return warpMessage; + } + + function initiateValidatorWeightUpdate( + bytes32 validationID, + uint64 newWeight + ) public onlyOwner returns (uint64, bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + if ($._validationPeriods[validationID].status != ValidatorStatus.Active) { + revert InvalidValidatorStatus($._validationPeriods[validationID].status); + } + + return _initiateValidatorWeightUpdate(validationID, newWeight); + } + + /** + * @notice See {ACP99Manager-_initiateValidatorWeightUpdate}. + * @dev This function modifies the validator's state. Callers should ensure that any references are updated. + */ + function _initiateValidatorWeightUpdate( + bytes32 validationID, + uint64 newWeight + ) internal virtual override returns (uint64, bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + uint64 validatorWeight = $._validationPeriods[validationID].weight; + + // Check that changing the validator weight would not exceed the maximum churn rate. + _checkAndUpdateChurnTracker(newWeight, validatorWeight); + + uint64 nonce = _incrementSentNonce(validationID); + + $._validationPeriods[validationID].weight = newWeight; + + // Submit the message to the Warp precompile. + bytes32 messageID = WARP_MESSENGER.sendWarpMessage( + ValidatorMessages.packL1ValidatorWeightMessage(validationID, nonce, newWeight) + ); + + emit InitiatedValidatorWeightUpdate({ + validationID: validationID, + nonce: nonce, + weightUpdateMessageID: messageID, + weight: newWeight + }); + + return (nonce, messageID); + } + + /** + * @notice See {IACP99Manager-completeValidatorWeightUpdate}. + */ + function completeValidatorWeightUpdate( + uint32 messageIndex + ) public virtual override onlyOwner returns (bytes32, uint64) { + WarpMessage memory warpMessage = _getPChainWarpMessage(messageIndex); + (bytes32 validationID, uint64 nonce, uint64 weight) = + ValidatorMessages.unpackL1ValidatorWeightMessage(warpMessage.payload); + + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + // The received nonce should be no greater than the highest sent nonce to ensure + // that weight changes are only initiated by this contract. + if ($._validationPeriods[validationID].sentNonce < nonce) { + revert InvalidNonce(nonce); + } + + $._validationPeriods[validationID].receivedNonce = nonce; + + emit CompletedValidatorWeightUpdate(validationID, nonce, weight); + + return (validationID, nonce); + } + + function getChurnPeriodSeconds() public view returns (uint64) { + return _getValidatorManagerStorage()._churnPeriodSeconds; + } + + /** + * @dev Helper function to check if the stake weight to be added or removed would exceed the maximum stake churn + * rate for the past churn period. If the churn rate is exceeded, the function will revert. If the churn rate is + * not exceeded, the function will update the churn tracker with the new weight. + */ + function _checkAndUpdateChurnTracker( + uint64 newValidatorWeight, + uint64 oldValidatorWeight + ) private { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + uint64 weightChange; + if (newValidatorWeight > oldValidatorWeight) { + weightChange = newValidatorWeight - oldValidatorWeight; + } else { + weightChange = oldValidatorWeight - newValidatorWeight; + } + + uint256 currentTime = block.timestamp; + ValidatorChurnPeriod memory churnTracker = $._churnTracker; + + if ( + churnTracker.startTime == 0 + || currentTime >= churnTracker.startTime + $._churnPeriodSeconds + ) { + churnTracker.churnAmount = weightChange; + churnTracker.startTime = currentTime; + churnTracker.initialWeight = churnTracker.totalWeight; + } else { + // Churn is always additive whether the weight is being added or removed. + churnTracker.churnAmount += weightChange; + } + + // Rearranged equation of maximumChurnPercentage >= currentChurnPercentage to avoid integer division truncation. + if ($._maximumChurnPercentage * churnTracker.initialWeight < churnTracker.churnAmount * 100) + { + revert MaxChurnRateExceeded(churnTracker.churnAmount); + } + + // Two separate calculations because we're using uints and (newValidatorWeight - oldValidatorWeight) could underflow. + churnTracker.totalWeight += newValidatorWeight; + churnTracker.totalWeight -= oldValidatorWeight; + + // Rearranged equation for totalWeight < (100 / $._maximumChurnPercentage) + // Total weight must be above this value in order to not trigger churn limits with an added/removed weight of 1. + if (churnTracker.totalWeight * $._maximumChurnPercentage < 100) { + revert InvalidTotalWeight(churnTracker.totalWeight); + } + + $._churnTracker = churnTracker; + } + + /** + * @notice Converts a nodeID to a fixed length of 20 bytes. + * @param nodeID The nodeID to convert. + * @return The fixed length nodeID. + */ + function _fixedNodeID( + bytes memory nodeID + ) private pure returns (bytes20) { + bytes20 fixedID; + // solhint-disable-next-line no-inline-assembly + assembly { + fixedID := mload(add(nodeID, 32)) + } + return fixedID; + } +} diff --git a/icm-contracts/contracts/validator-manager/ValidatorMessages.sol b/icm-contracts/contracts/validator-manager/ValidatorMessages.sol new file mode 100644 index 000000000..2412ab733 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/ValidatorMessages.sol @@ -0,0 +1,659 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem +pragma solidity 0.8.25; + +import {PChainOwner, ConversionData} from "./interfaces/IACP99Manager.sol"; + +/** + * @dev Packing utilities for the ICM message types used by the Validator Manager contracts, as specified in ACP-77: + * https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets + */ +library ValidatorMessages { + // The information that uniquely identifies an L1 validation period. + // The validationID is the SHA-256 hash of the concatenation of the CODEC_ID, + // REGISTER_L1_VALIDATOR_MESSAGE_TYPE_ID, and the concatenated ValidationPeriod fields. + struct ValidationPeriod { + bytes32 subnetID; + bytes nodeID; + bytes blsPublicKey; + uint64 registrationExpiry; + PChainOwner remainingBalanceOwner; + PChainOwner disableOwner; + uint64 weight; + } + + // The P-Chain uses a hardcoded codecID of 0 for all messages. + uint16 internal constant CODEC_ID = 0; + + // The P-Chain signs a SubnetToL1ConversionMessage that is used to verify the L1's initial validators. + uint32 internal constant SUBNET_TO_L1_CONVERSION_MESSAGE_TYPE_ID = 0; + + // L1s send a RegisterL1ValidatorMessage to the P-Chain to register a validator. + uint32 internal constant REGISTER_L1_VALIDATOR_MESSAGE_TYPE_ID = 1; + + // The P-Chain responds with a RegisterL1ValidatorMessage indicating whether the registration was successful + // for the given validation ID. + uint32 internal constant L1_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID = 2; + + // L1s can send a L1ValidatorWeightMessage to the P-Chain to update a validator's weight. + // The P-Chain responds with another L1ValidatorWeightMessage acknowledging the weight update. + uint32 internal constant L1_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID = 3; + + // The L1 will self-sign a ValidationUptimeMessage to be provided when a validator is initiating + // the end of their validation period. + uint32 internal constant VALIDATION_UPTIME_MESSAGE_TYPE_ID = 0; + + error InvalidMessageLength(uint32 actual, uint32 expected); + error InvalidCodecID(uint32 id); + error InvalidMessageType(); + error InvalidBLSPublicKey(); + + /** + * @notice Packs a SubnetToL1ConversionMessage message into a byte array. + * The message format specification is: + * +--------------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------------+----------+----------+ + * | conversionID : [32]byte | 32 bytes | + * +--------------------+----------+----------+ + * | 38 bytes | + * +----------+ + * + * @param conversionID The subnet conversion ID to pack into the message. + * @return The packed message. + */ + function packSubnetToL1ConversionMessage( + bytes32 conversionID + ) external pure returns (bytes memory) { + return abi.encodePacked(CODEC_ID, SUBNET_TO_L1_CONVERSION_MESSAGE_TYPE_ID, conversionID); + } + + /** + * @notice Unpacks a byte array as a SubnetToL1ConversionMessage message. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The unpacked conversionID. + */ + function unpackSubnetToL1ConversionMessage( + bytes memory input + ) external pure returns (bytes32) { + if (input.length != 38) { + revert InvalidMessageLength(uint32(input.length), 38); + } + + // Unpack the codec ID + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(codecID); + } + + // Unpack the type ID + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != SUBNET_TO_L1_CONVERSION_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the conversionID + bytes32 conversionID; + for (uint256 i; i < 32; ++i) { + conversionID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + return conversionID; + } + + /** + * @notice Packs ConversionData into a byte array. + * This byte array is the SHA256 pre-image of the conversionID hash + * The message format specification is: + * + * ConversionData: + * +----------------+-----------------+--------------------------------------------------------+ + * | codecID : uint16 | 2 bytes | + * +----------------+-----------------+--------------------------------------------------------+ + * | subnetID : [32]byte | 32 bytes | + * +----------------+-----------------+--------------------------------------------------------+ + * | managerChainID : [32]byte | 32 bytes | + * +----------------+-----------------+--------------------------------------------------------+ + * | managerAddress : []byte | 4 + len(managerAddress) bytes | + * +----------------+-----------------+--------------------------------------------------------+ + * | validators : []ValidatorData | 4 + sum(validatorLengths) bytes | + * +----------------+-----------------+--------------------------------------------------------+ + * | 74 + len(managerAddress) + len(validatorLengths) bytes | + * +--------------------------------------------------------+ + * ValidatorData: + * +--------------+----------+------------------------+ + * | nodeID : []byte | 4 + len(nodeID) bytes | + * +--------------+----------+------------------------+ + * | blsPublicKey : [48]byte | 48 bytes | + * +--------------+----------+------------------------+ + * | weight : uint64 | 8 bytes | + * +--------------+----------+------------------------+ + * | 60 + len(nodeID) bytes | + * +------------------------+ + * + * @dev Input validation is skipped, since the returned value is intended to be compared + * directly with an authenticated ICM message. + * @param conversionData The struct representing data to pack into the message. + * @return The packed message. + */ + function packConversionData( + ConversionData memory conversionData + ) external pure returns (bytes memory) { + // Hardcoded 20 is for length of the managerAddress on EVM chains + // solhint-disable-next-line func-named-parameters + bytes memory res = abi.encodePacked( + CODEC_ID, + conversionData.subnetID, + conversionData.validatorManagerBlockchainID, + uint32(20), + conversionData.validatorManagerAddress, + uint32(conversionData.initialValidators.length) + ); + // The approach below of encoding initialValidators using `abi.encodePacked` in a loop + // was tested against pre-allocating the array and doing manual byte by byte packing and + // it was found to be more gas efficient. + for (uint256 i; i < conversionData.initialValidators.length; ++i) { + res = abi.encodePacked( + res, + uint32(conversionData.initialValidators[i].nodeID.length), + conversionData.initialValidators[i].nodeID, + conversionData.initialValidators[i].blsPublicKey, + conversionData.initialValidators[i].weight + ); + } + return res; + } + + /** + * @notice Packs a RegisterL1ValidatorMessage message into a byte array. + * The message format specification is: + * + * RegisterL1ValidatorMessage: + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | codecID : uint16 | 2 bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | typeID : uint32 | 4 bytes | + * +-----------------------+-------------+-------------------------------------------------------------------+ + * | subnetID : [32]byte | 32 bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | nodeID : []byte | 4 + len(nodeID) bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | blsPublicKey : [48]byte | 48 bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | expiry : uint64 | 8 bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | remainingBalanceOwner : PChainOwner | 8 + len(addresses) * 20 bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | disableOwner : PChainOwner | 8 + len(addresses) * 20 bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | weight : uint64 | 8 bytes | + * +-----------------------+-------------+--------------------------------------------------------------------+ + * | 122 + len(nodeID) + (len(addresses1) + len(addresses2)) * 20 bytes | + * +--------------------------------------------------------------------+ + * + * PChainOwner: + * +-----------+------------+-------------------------------+ + * | threshold : uint32 | 4 bytes | + * +-----------+------------+-------------------------------+ + * | addresses : [][20]byte | 4 + len(addresses) * 20 bytes | + * +-----------+------------+-------------------------------+ + * | 8 + len(addresses) * 20 bytes | + * +-------------------------------+ + * + * @param validationPeriod The information to pack into the message. + * @return The validationID and the packed message. + */ + function packRegisterL1ValidatorMessage( + ValidationPeriod memory validationPeriod + ) external pure returns (bytes32, bytes memory) { + if (validationPeriod.blsPublicKey.length != 48) { + revert InvalidBLSPublicKey(); + } + + // solhint-disable-next-line func-named-parameters + bytes memory res = abi.encodePacked( + CODEC_ID, + REGISTER_L1_VALIDATOR_MESSAGE_TYPE_ID, + validationPeriod.subnetID, + uint32(validationPeriod.nodeID.length), + validationPeriod.nodeID, + validationPeriod.blsPublicKey, + validationPeriod.registrationExpiry, + validationPeriod.remainingBalanceOwner.threshold, + uint32(validationPeriod.remainingBalanceOwner.addresses.length) + ); + for (uint256 i; i < validationPeriod.remainingBalanceOwner.addresses.length; ++i) { + res = abi.encodePacked(res, validationPeriod.remainingBalanceOwner.addresses[i]); + } + res = abi.encodePacked( + res, + validationPeriod.disableOwner.threshold, + uint32(validationPeriod.disableOwner.addresses.length) + ); + for (uint256 i; i < validationPeriod.disableOwner.addresses.length; ++i) { + res = abi.encodePacked(res, validationPeriod.disableOwner.addresses[i]); + } + res = abi.encodePacked(res, validationPeriod.weight); + + return (sha256(res), res); + } + + /** + * @notice Unpacks a byte array as a RegisterL1ValidatorMessage message. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The unpacked ValidationPeriod. + */ + function unpackRegisterL1ValidatorMessage( + bytes memory input + ) external pure returns (ValidationPeriod memory) { + uint32 index; + ValidationPeriod memory validation; + + // Unpack the codec ID + // Individual fields are unpacked in their own scopes to avoid stack too deep errors. + { + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i + index])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(codecID); + } + index += 2; + } + + // Unpack the type ID + { + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + index])) << uint32((8 * (3 - i))); + } + if (typeID != REGISTER_L1_VALIDATOR_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + index += 4; + } + + // Unpack the subnetID + { + bytes32 subnetID; + for (uint256 i; i < 32; ++i) { + subnetID |= bytes32(uint256(uint8(input[i + index])) << (8 * (31 - i))); + } + validation.subnetID = subnetID; + index += 32; + } + + // Unpack the nodeID length + uint32 nodeIDLength; + { + for (uint256 i; i < 4; ++i) { + nodeIDLength |= uint32(uint8(input[i + index])) << uint32((8 * (3 - i))); + } + index += 4; + + // Unpack the nodeID + bytes memory nodeID = new bytes(nodeIDLength); + for (uint256 i; i < nodeIDLength; ++i) { + nodeID[i] = input[i + index]; + } + validation.nodeID = nodeID; + index += nodeIDLength; + } + + // Unpack the blsPublicKey + { + bytes memory blsPublicKey = new bytes(48); + for (uint256 i; i < 48; ++i) { + blsPublicKey[i] = input[i + index]; + } + validation.blsPublicKey = blsPublicKey; + index += 48; + } + + // Unpack the registration expiry + { + uint64 expiry; + for (uint256 i; i < 8; ++i) { + expiry |= uint64(uint8(input[i + index])) << uint64((8 * (7 - i))); + } + validation.registrationExpiry = expiry; + index += 8; + } + + // Unpack the remainingBalanceOwner threshold + uint32 remainingBalanceOwnerAddressesLength; + { + uint32 remainingBalanceOwnerThreshold; + for (uint256 i; i < 4; ++i) { + remainingBalanceOwnerThreshold |= + uint32(uint8(input[i + index])) << uint32((8 * (3 - i))); + } + index += 4; + + // Unpack the remainingBalanceOwner addresses length + for (uint256 i; i < 4; ++i) { + remainingBalanceOwnerAddressesLength |= + uint32(uint8(input[i + index])) << uint32((8 * (3 - i))); + } + index += 4; + + // Unpack the remainingBalanceOwner addresses + address[] memory remainingBalanceOwnerAddresses = + new address[](remainingBalanceOwnerAddressesLength); + for (uint256 i; i < remainingBalanceOwnerAddressesLength; ++i) { + bytes memory addrBytes = new bytes(20); + for (uint256 j; j < 20; ++j) { + addrBytes[j] = input[j + index]; + } + address addr; + // solhint-disable-next-line no-inline-assembly + assembly { + addr := mload(add(addrBytes, 20)) + } + remainingBalanceOwnerAddresses[i] = addr; + index += 20; + } + validation.remainingBalanceOwner = PChainOwner({ + threshold: remainingBalanceOwnerThreshold, + addresses: remainingBalanceOwnerAddresses + }); + } + + // Unpack the disableOwner threshold + uint32 disableOwnerAddressesLength; + { + uint32 disableOwnerThreshold; + for (uint256 i; i < 4; ++i) { + disableOwnerThreshold |= uint32(uint8(input[i + index])) << uint32((8 * (3 - i))); + } + index += 4; + + // Unpack the disableOwner addresses length + for (uint256 i; i < 4; ++i) { + disableOwnerAddressesLength |= + uint32(uint8(input[i + index])) << uint32((8 * (3 - i))); + } + index += 4; + + // Unpack the disableOwner addresses + address[] memory disableOwnerAddresses = new address[](disableOwnerAddressesLength); + for (uint256 i; i < disableOwnerAddressesLength; ++i) { + bytes memory addrBytes = new bytes(20); + for (uint256 j; j < 20; ++j) { + addrBytes[j] = input[j + index]; + } + address addr; + // solhint-disable-next-line no-inline-assembly + assembly { + addr := mload(add(addrBytes, 20)) + } + disableOwnerAddresses[i] = addr; + index += 20; + } + validation.disableOwner = + PChainOwner({threshold: disableOwnerThreshold, addresses: disableOwnerAddresses}); + } + // Now that we have all the variable lengths, validate the input length + uint32 expectedLength = 122 + nodeIDLength + + (remainingBalanceOwnerAddressesLength + disableOwnerAddressesLength) * 20; + if (input.length != expectedLength) { + revert InvalidMessageLength(uint32(input.length), expectedLength); + } + // Unpack the weight + { + uint64 weight; + for (uint256 i; i < 8; ++i) { + weight |= uint64(uint8(input[i + index])) << uint64((8 * (7 - i))); + } + validation.weight = weight; + } + + return validation; + } + + /** + * @notice Packs a L1ValidatorRegistrationMessage into a byte array. + * The message format specification is: + * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+----------+ + * | validationID : [32]byte | 32 bytes | + * +--------------+----------+----------+ + * | registered : bool | 1 byte | + * +--------------+----------+----------+ + * | 39 bytes | + * +----------+ + * + * @param validationID The ID of the validation period. + * @param registered true if the validation period was registered, false if it was not and never will be. + * @return The packed message. + * + */ + function packL1ValidatorRegistrationMessage( + bytes32 validationID, + bool registered + ) external pure returns (bytes memory) { + return abi.encodePacked( + CODEC_ID, L1_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID, validationID, registered + ); + } + + /** + * @notice Unpacks a byte array as a L1ValidatorRegistrationMessage message. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The validationID and whether the validation period was registered or is not a + * validator and never will be a validator due to the expiry time passing. + */ + function unpackL1ValidatorRegistrationMessage( + bytes memory input + ) external pure returns (bytes32, bool) { + if (input.length != 39) { + revert InvalidMessageLength(uint32(input.length), 39); + } + // Unpack the codec ID + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(codecID); + } + + // Unpack the type ID + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != L1_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the validation ID. + bytes32 validationID; + for (uint256 i; i < 32; ++i) { + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the validity + bool registered = input[38] != 0; + + return (validationID, registered); + } + + /** + * @notice Packs a L1ValidatorWeightMessage message into a byte array. + * The message format specification is: + * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+----------+ + * | validationID : [32]byte | 32 bytes | + * +--------------+----------+----------+ + * | nonce : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | weight : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | 54 bytes | + * +----------+ + * + * @param validationID The ID of the validation period. + * @param nonce The nonce of the validation ID. + * @param weight The new weight of the validator. + * @return The packed message. + */ + function packL1ValidatorWeightMessage( + bytes32 validationID, + uint64 nonce, + uint64 weight + ) external pure returns (bytes memory) { + return abi.encodePacked( + CODEC_ID, L1_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID, validationID, nonce, weight + ); + } + + /** + * @notice Unpacks a byte array as an L1ValidatorWeightMessage. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The validationID, nonce, and weight. + */ + function unpackL1ValidatorWeightMessage( + bytes memory input + ) external pure returns (bytes32, uint64, uint64) { + if (input.length != 54) { + revert InvalidMessageLength(uint32(input.length), 54); + } + + // Unpack the codec ID. + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(codecID); + } + + // Unpack the type ID. + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != L1_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the validation ID. + bytes32 validationID; + for (uint256 i; i < 32; ++i) { + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the nonce. + uint64 nonce; + for (uint256 i; i < 8; ++i) { + nonce |= uint64(uint8(input[i + 38])) << uint64((8 * (7 - i))); + } + + // Unpack the weight. + uint64 weight; + for (uint256 i; i < 8; ++i) { + weight |= uint64(uint8(input[i + 46])) << uint64((8 * (7 - i))); + } + + return (validationID, nonce, weight); + } + + /** + * @notice Packs a ValidationUptimeMessage into a byte array. + * The message format specification is: + * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+----------+ + * | validationID : [32]byte | 32 bytes | + * +--------------+----------+----------+ + * | uptime : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | 46 bytes | + * +----------+ + * + * @param validationID The ID of the validation period. + * @param uptime The uptime of the validator. + * @return The packed message. + */ + function packValidationUptimeMessage( + bytes32 validationID, + uint64 uptime + ) external pure returns (bytes memory) { + return abi.encodePacked(CODEC_ID, VALIDATION_UPTIME_MESSAGE_TYPE_ID, validationID, uptime); + } + + /** + * @notice Unpacks a byte array as a ValidationUptimeMessage. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The validationID and uptime. + */ + function unpackValidationUptimeMessage( + bytes memory input + ) external pure returns (bytes32, uint64) { + if (input.length != 46) { + revert InvalidMessageLength(uint32(input.length), 46); + } + + // Unpack the codec ID. + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(codecID); + } + + // Unpack the type ID. + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != VALIDATION_UPTIME_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the validation ID. + bytes32 validationID; + for (uint256 i; i < 32; ++i) { + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the uptime. + uint64 uptime; + for (uint256 i; i < 8; ++i) { + uptime |= uint64(uint8(input[i + 38])) << uint64((8 * (7 - i))); + } + + return (validationID, uptime); + } +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IACP99Manager.sol b/icm-contracts/contracts/validator-manager/interfaces/IACP99Manager.sol new file mode 100644 index 000000000..c7f07d3b6 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IACP99Manager.sol @@ -0,0 +1,183 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/// @notice L1 validator status. +enum ValidatorStatus { + Unknown, + PendingAdded, + Active, + PendingRemoved, + Completed, + Invalidated +} + +/** + * @notice Description of the conversion data used to convert + * a subnet to an L1 on the P-Chain. + * This data is the pre-image of a hash that is authenticated by the P-Chain + * and verified by the Validator Manager. + */ +struct ConversionData { + bytes32 subnetID; + bytes32 validatorManagerBlockchainID; + address validatorManagerAddress; + InitialValidator[] initialValidators; +} + +/// @notice Specifies an initial validator, used in the conversion data. +struct InitialValidator { + bytes nodeID; + bytes blsPublicKey; + uint64 weight; +} + +/** + * @notice Specifies the owner of a validator's remaining balance or disable owner on the P-Chain. + * P-Chain addresses are also 20-bytes, so we use the address type to represent them. + */ +struct PChainOwner { + uint32 threshold; + address[] addresses; +} + +/** + * @notice Contains the active state of a Validator. + * @param status The validator status. + * @param nodeID The NodeID of the validator. + * @param startingWeight The weight of the validator at the time of registration. + * @param sentNonce The current weight update nonce sent by the manager. + * @param receivedNonce The highest nonce received from the P-Chain. + * @param weight The current weight of the validator. + * @param startTime The start time of the validator. + * @param endTime The end time of the validator. + */ +struct Validator { + ValidatorStatus status; + bytes nodeID; + uint64 startingWeight; + uint64 sentNonce; + uint64 receivedNonce; + uint64 weight; + uint64 startTime; + uint64 endTime; +} + +/* + * @title IACP99Manager + * @notice The IACP99Manager interface represents the functionality for sovereign L1 + * validator management, as specified in ACP-77. + * + * @dev IACP99Manager defines the public functions specified in ACP-99. + * The counterpart to this interface is ACP99Manager, which defines the private functions specified in ACP-99. + * https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/99-validatorsetmanager-contract + */ +interface IACP99Manager { + /** + * @notice Emitted when an initial validator is registered. + * @notice The field index is the index of the initial validator in the conversion data. + * This is used along with the subnetID as the ACP-118 justification in + * signature requests to P-Chain validators over a L1ValidatorRegistrationMessage + * when removing the validator + */ + event RegisteredInitialValidator( + bytes32 indexed validationID, + bytes20 indexed nodeID, + bytes32 indexed subnetID, + uint64 weight + ); + /// @notice Emitted when a validator registration to the L1 is initiated. + event InitiatedValidatorRegistration( + bytes32 indexed validationID, + bytes20 indexed nodeID, + bytes32 registrationMessageID, + uint64 registrationExpiry, + uint64 weight + ); + /// @notice Emitted when a validator registration to the L1 is completed. + event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight); + /// @notice Emitted when removal of an L1 validator is initiated. + event InitiatedValidatorRemoval( + bytes32 indexed validationID, + bytes32 validatorWeightMessageID, + uint64 weight, + uint64 endTime + ); + /// @notice Emitted when removal of an L1 validator is completed. + event CompletedValidatorRemoval(bytes32 indexed validationID); + /// @notice Emitted when a validator weight update is initiated. + event InitiatedValidatorWeightUpdate( + bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight + ); + /// @notice Emitted when a validator weight update is completed. + event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight); + + /** + * @notice Verifies and sets the initial validator set for the chain by consuming a + * SubnetToL1ConversionMessage from the P-Chain. + * + * Emits a {RegisteredInitialValidator} event for each initial validator in {conversionData}. + * + * @param conversionData The Subnet conversion message data used to recompute and verify against the ConversionID. + * @param messageIndex The index that contains the SubnetToL1ConversionMessage ICM message containing the + * ConversionID to be verified against the provided {conversionData}. + */ + function initializeValidatorSet( + ConversionData calldata conversionData, + uint32 messageIndex + ) external; + + /** + * @notice Completes the validator registration process by returning an acknowledgement of the registration of a + * validationID from the P-Chain. The validator should not be considered active until this method is successfully called. + * + * Emits a {CompletedValidatorRegistration} event on success. + * + * @param messageIndex The index of the L1ValidatorRegistrationMessage to be received providing the acknowledgement. + * @return validationID The ID of the registered validator. + */ + function completeValidatorRegistration( + uint32 messageIndex + ) external returns (bytes32 validationID); + + /** + * @notice Completes validator removal by consuming a RegisterL1ValidatorMessage from the P-Chain acknowledging + * that the validator has been removed, or that it was not registered on the P-Chain and the expiry time has passed. + * + * Emits a {CompletedValidatorRemoval} on success. + * + * @param messageIndex The index of the RegisterL1ValidatorMessage. + * @return validationID The ID of the validator that was removed. + */ + function completeValidatorRemoval( + uint32 messageIndex + ) external returns (bytes32 validationID); + + /** + * @notice Completes the validator weight update process by consuming an L1ValidatorWeightMessage from the P-Chain + * acknowledging the weight update. The validator weight change should not have any effect until this method is successfully called. + * + * Emits a {CompletedValidatorWeightUpdate} event on success. + * + * @param messageIndex The index of the L1ValidatorWeightMessage message to be received providing the acknowledgement. + * @return validationID The ID of the validator, retreived from the L1ValidatorWeightMessage. + * @return nonce The nonce of the validator, retreived from the L1ValidatorWeightMessage. + */ + function completeValidatorWeightUpdate( + uint32 messageIndex + ) external returns (bytes32 validationID, uint64 nonce); + + /// @notice Returns the SubnetID of the L1 tied to this manager + function subnetID() external view returns (bytes32 id); + + /// @notice Returns the validator details for a given validation ID. + function getValidator( + bytes32 validationID + ) external view returns (Validator memory validator); + + /// @notice Returns the total weight of the current L1 validator set. + function l1TotalWeight() external view returns (uint64 weight); +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IERC20Mintable.sol b/icm-contracts/contracts/validator-manager/interfaces/IERC20Mintable.sol new file mode 100644 index 000000000..4fe680ebd --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IERC20Mintable.sol @@ -0,0 +1,21 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; + +/** + * @notice Extension of the ERC20 standard that allows for minting new tokens. + */ +interface IERC20Mintable is IERC20 { + /** + * @notice Mint tokens to the specified address. + * @param account The address to mint tokens to. + * @param amount How many tokens to mint. + * @dev This function should have appropriate user controls to ensure that only authorized users can mint. + */ + function mint(address account, uint256 amount) external; +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IERC20TokenStakingManager.sol b/icm-contracts/contracts/validator-manager/interfaces/IERC20TokenStakingManager.sol new file mode 100644 index 000000000..d3f62a834 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IERC20TokenStakingManager.sol @@ -0,0 +1,50 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IStakingManager} from "./IStakingManager.sol"; +import {PChainOwner} from "../ACP99Manager.sol"; + +/** + * Proof of Stake Validator Manager that stakes ERC20 tokens. + */ +interface IERC20TokenStakingManager is IStakingManager { + /** + * @notice Begins the validator registration process. Locks the specified ERC20 tokens in the contract as the stake. + * @param nodeID The ID of the node to add to the L1. + * @param blsPublicKey The BLS public key of the validator. + * @param remainingBalanceOwner The remaining balance owner of the validator. + * @param disableOwner The disable owner of the validator. + * @param delegationFeeBips The fee that delegators must pay to delegate to this validator. + * @param minStakeDuration The minimum amount of time this validator must be staked for in seconds. + * @param stakeAmount The amount of tokens to stake. + * @param rewardRecipient The address of the reward recipient. + * @return validationID The ID of the registered validator. + */ + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount, + address rewardRecipient + ) external returns (bytes32); + + /** + * @notice Begins the delegator registration process. Locks the specified ERC20 tokens in the contract as the stake. + * @param validationID The ID of the validator to stake to. + * @param stakeAmount The amount of tokens to stake. + * @param rewardRecipient The address of the reward recipient. + * @return delegationID The ID of the registered delegator. + */ + function initiateDelegatorRegistration( + bytes32 validationID, + uint256 stakeAmount, + address rewardRecipient + ) external returns (bytes32); +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/INativeTokenStakingManager.sol b/icm-contracts/contracts/validator-manager/interfaces/INativeTokenStakingManager.sol new file mode 100644 index 000000000..93f7b6b14 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/INativeTokenStakingManager.sol @@ -0,0 +1,46 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IStakingManager} from "./IStakingManager.sol"; +import {PChainOwner} from "../ACP99Manager.sol"; + +/** + * Proof of Stake Validator Manager that stakes the blockchain's native tokens. + */ +interface INativeTokenStakingManager is IStakingManager { + /** + * @notice Begins the validator registration process. Locks the provided native asset in the contract as the stake. + * @param nodeID The ID of the node to add to the L1. + * @param blsPublicKey The BLS public key of the validator. + * @param remainingBalanceOwner The remaining balance owner of the validator. + * @param disableOwner The disable owner of the validator. + * @param delegationFeeBips The fee that delegators must pay to delegate to this validator. + * @param minStakeDuration The minimum amount of time this validator must be staked for in seconds. + * @param rewardRecipient The address of the reward recipient. + * @return validationID The ID of the registered validator. + */ + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + address rewardRecipient + ) external payable returns (bytes32); + + /** + * @notice Begins the delegator registration process. Locks the provided native asset in the contract as the stake. + * @param validationID The ID of the validator to stake to. + * @param rewardRecipient The address of the reward recipient. + * @return delegationID The ID of the registered delegator. + */ + function initiateDelegatorRegistration( + bytes32 validationID, + address rewardRecipient + ) external payable returns (bytes32); +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IPoAManager.sol b/icm-contracts/contracts/validator-manager/interfaces/IPoAManager.sol new file mode 100644 index 000000000..dc6260b22 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IPoAManager.sol @@ -0,0 +1,91 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {PChainOwner} from "./IACP99Manager.sol"; + +/** + * @dev Proof-of-authority manager interface meant to be used as the owner of an + * {IValidatorManager} contract instance that only allows modifications to the validator set + * to be initiated by a fixed address. Once initiated, modifications are meant to be able to be + * completed by any address to allow for improved UX flows. + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface IPoAManager { + /** + * @notice Initiates validator registration. Only callable by the contract owner. + * @param nodeID The node ID of the validator. + * @param blsPublicKey The BLS public key of the validator. + * @param remainingBalanceOwner The P-chain owner for remaining balance. + * @param disableOwner The P-chain owner for disabling. + * @param weight The validator's weight. + * @return validationID The unique identifier for the validator registration. + */ + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) external returns (bytes32 validationID); + + /** + * @notice Initiates validator removal. Only callable by the contract owner. + * @param validationID The unique identifier of the validator to remove. + */ + function initiateValidatorRemoval( + bytes32 validationID + ) external; + + /** + * @notice Initiates a validator weight update. Only callable by the contract owner. + * @param validationID The unique identifier of the validator. + * @param newWeight The new weight for the validator. + * @return nonce The validator nonce associated with the weight change. + * @return messageID The ICM message ID of the L1ValidatorWeightMessage that executes the weight change on the P-Chain. + */ + function initiateValidatorWeightUpdate( + bytes32 validationID, + uint64 newWeight + ) external returns (uint64 nonce, bytes32 messageID); + + /** + * @notice Completes validator registration. Callable by anyone. + * @param messageIndex The index of the registration message. + * @return validationID The unique identifier for the completed registration. + */ + function completeValidatorRegistration( + uint32 messageIndex + ) external returns (bytes32 validationID); + + /** + * @notice Completes validator removal. Callable by anyone. + * @param messageIndex The index of the removal message. + * @return validationID The unique identifier for the completed removal. + */ + function completeValidatorRemoval( + uint32 messageIndex + ) external returns (bytes32 validationID); + + /** + * @notice Completes a validator weight update. Callable by anyone. + * @param messageIndex The index of the weight update message. + * @return validationID The unique identifier for the validator whose weight was updated. + * @return nonce The validator nonce associated with the executed weight change. + */ + function completeValidatorWeightUpdate( + uint32 messageIndex + ) external returns (bytes32 validationID, uint64 nonce); + + /** + * @notice Transfers ownership of the validator manager contract. + * @param newOwner The address to transfer ownership to. + */ + function transferValidatorManagerOwnership( + address newOwner + ) external; +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IRewardCalculator.sol b/icm-contracts/contracts/validator-manager/interfaces/IRewardCalculator.sol new file mode 100644 index 000000000..e3ee1a23a --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IRewardCalculator.sol @@ -0,0 +1,27 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +/** + * @notice Interface for Validation and Delegation reward calculators + */ +interface IRewardCalculator { + /** + * @notice Calculate the reward for a staker (validator or delegator) + * @param stakeAmount The amount of tokens staked + * @param validatorStartTime The time the validator started validating + * @param stakingStartTime The time the staker started staking + * @param stakingEndTime The time the staker stopped staking + * @param uptimeSeconds The total time the validator was validating + */ + function calculateReward( + uint256 stakeAmount, + uint64 validatorStartTime, + uint64 stakingStartTime, + uint64 stakingEndTime, + uint64 uptimeSeconds + ) external view returns (uint256); +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IStakingManager.sol b/icm-contracts/contracts/validator-manager/interfaces/IStakingManager.sol new file mode 100644 index 000000000..2012b8259 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IStakingManager.sol @@ -0,0 +1,349 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IValidatorManager} from "../interfaces/IValidatorManager.sol"; +import {IRewardCalculator} from "./IRewardCalculator.sol"; + +/** + * @dev Delegator status + */ +enum DelegatorStatus { + Unknown, + PendingAdded, + Active, + PendingRemoved +} + +/** + * @notice Staking Manager settings, used to initialize the Staking Manager + * @notice baseSettings specified the base settings for the Validator Manager. See {IValidatorManager-ValidatorManagerSettings} + * @notice minimumStakeAmount is the minimum amount of stake required to stake to a validator + * @notice maximumStakeAmount is the maximum amount of stake that can be staked to a validator + * @notice minimumStakeDuration is the minimum duration that validators must stake for + * @notice minimumDelegationFeeBips is the minimum delegation fee in basis points that validators can charge + * @notice maximumStakeMultiplier is the multiplier applied to validator's initial stake amount to determine + * the maximum amount of stake a validator can have with delegations. + * @notice weightToValueFactor is the factor used to convert validator weight to value + * @notice rewardCalculator is the reward calculator used to calculate rewards for this validator manager + * @notice uptimeBlockchainID is the ID of the blockchain that submits uptime proofs. + * This must be a blockchain validated by the subnetID that this contract manages. + */ +struct StakingManagerSettings { + IValidatorManager manager; + uint256 minimumStakeAmount; + uint256 maximumStakeAmount; + uint64 minimumStakeDuration; + uint16 minimumDelegationFeeBips; + uint8 maximumStakeMultiplier; + uint256 weightToValueFactor; + IRewardCalculator rewardCalculator; + bytes32 uptimeBlockchainID; +} + +/** + * @dev Contains the active state of a Delegator + */ +struct Delegator { + DelegatorStatus status; + address owner; + bytes32 validationID; + uint64 weight; + uint64 startTime; + uint64 startingNonce; + uint64 endingNonce; +} + +/** + * @dev Describes the active state of a PoS Validator in addition the information in {IValidatorManager-Validator} + */ +struct PoSValidatorInfo { + address owner; + uint16 delegationFeeBips; + uint64 minStakeDuration; + uint64 uptimeSeconds; +} + +/** + * @notice Interface for Proof of Stake Validator Managers + */ +interface IStakingManager { + /** + * @notice Event emitted when a delegator registration is initiated + * @param delegationID The ID of the delegation + * @param validationID The ID of the validation period being delegated to + * @param delegatorAddress The address of the delegator + * @param nonce The message nonce used to update the validator weight + * @param validatorWeight The updated validator weight that is sent to the P-Chain + * @param delegatorWeight The weight of the delegator + * @param setWeightMessageID The ID of the ICM message that updates the validator's weight on the P-Chain + * @param rewardRecipient The address of the recipient of the delegator's rewards + */ + event InitiatedDelegatorRegistration( + bytes32 indexed delegationID, + bytes32 indexed validationID, + address indexed delegatorAddress, + uint64 nonce, + uint64 validatorWeight, + uint64 delegatorWeight, + bytes32 setWeightMessageID, + address rewardRecipient + ); + + /** + * @notice Event emitted when a staking validator registration is initiated + * @param validationID The ID of the validation period + * @param owner The address of the owner of the validator + * @param delegationFeeBips The delegation fee in basis points + * @param minStakeDuration The minimum stake duration + * @param rewardRecipient The address of the recipient of the validator's rewards + */ + event InitiatedStakingValidatorRegistration( + bytes32 indexed validationID, + address indexed owner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + address rewardRecipient + ); + + /** + * @notice Event emitted when a delegator registration is completed + * @param delegationID The ID of the delegation + * @param validationID The ID of the validation period + * @param startTime The time at which the registration was completed + */ + event CompletedDelegatorRegistration( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime + ); + + /** + * @notice Event emitted when delegator removal is initiated + * @param delegationID The ID of the delegation + * @param validationID The ID of the validation period the delegator was staked to + */ + event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID); + + /** + * @notice Event emitted when delegator removal is completed + * @param delegationID The ID of the delegation + * @param validationID The ID of the validator the delegator was staked to + * @param rewards The rewards given to the delegator + * @param fees The portion of the delegator's rewards paid to the validator + */ + event CompletedDelegatorRemoval( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees + ); + + /** + * @notice Event emitted when the uptime of a validator is updated. Only emitted when the uptime is greater than the stored uptime. + * @param validationID The ID of the validation period + * @param uptime The updated uptime of the validator + */ + event UptimeUpdated(bytes32 indexed validationID, uint64 uptime); + + /** + * @notice Event emitted when a validator claims rewards. Emitted when validation rewards and delegation fees are claimed. + * @param validationID The ID of the validation period + * @param recipient The address of the recipient of the rewards + * @param amount The amount of rewards claimed + */ + event ValidatorRewardClaimed( + bytes32 indexed validationID, address indexed recipient, uint256 amount + ); + + /** + * @notice Event emitted when the recipient of a validator's rewards is changed. + * @param validationID The ID of the validation period + * @param recipient The address of the new recipient of the rewards + * @param oldRecipient The address of the old recipient of the rewards + */ + event ValidatorRewardRecipientChanged( + bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient + ); + + /** + * @notice Event emitted when a delegator claims rewards. + * @param delegationID The ID of the delegation + * @param recipient The address of the recipient of the rewards + * @param amount The amount of rewards claimed + */ + event DelegatorRewardClaimed( + bytes32 indexed delegationID, address indexed recipient, uint256 amount + ); + + /** + * @notice Event emitted when the recipient of a delegator's rewards is changed. + * @param delegationID The ID of the validation period + * @param recipient The address of the new recipient of the rewards + * @param oldRecipient The address of the old recipient of the rewards + */ + event DelegatorRewardRecipientChanged( + bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient + ); + + /** + * @notice Updates the uptime of the validationID if the submitted proof is greated than the stored uptime. + * Anybody may call this function to ensure the stored uptime is accurate. Callable only when the validation period is active. + * @param validationID The ID of the validation period + * @param messageIndex The index of the ICM message to be received providing the uptime proof + */ + function submitUptimeProof(bytes32 validationID, uint32 messageIndex) external; + + /** + * @notice Completes validator registration by dispatching to the IValidatorManager to update the validator status, + * and locking stake. + * + * @param messageIndex The index of the ICM message to be received providing the acknowledgement from the P-Chain. + * This is forwarded to the IValidatorManager to be parsed. + * @return The ID of the validator that was registered. + */ + function completeValidatorRegistration( + uint32 messageIndex + ) external returns (bytes32); + + /** + * @notice Begins the process of ending an active validation period, and reverts if the validation period is not eligible + * for uptime-based rewards. This function is used to exit the validator set when rewards are expected. + * The validation period must have been previously started by a successful call to {completeValidatorRegistration} with the given validationID. + * Any rewards for this validation period will stop accruing when this function is called. + * Note: Reverts if the uptime is not eligible for rewards. + * @param validationID The ID of the validation period being ended. + * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. If no uptime proof is provided, + * the latest known uptime will be used. + * @param messageIndex The index of the ICM message to be received providing the uptime proof. + */ + function initiateValidatorRemoval( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) external; + + /** + * @notice Begins the process of ending an active validation period, but does not revert if the latest known uptime + * is not sufficient to collect uptime-based rewards. This function is used to exit the validator set when rewards are + * not expected. + * The validation period must have been previously started by a successful call to {completeValidatorRegistration} with the given validationID. + * Any rewards for this validation period will stop accruing when this function is called. + * @param validationID The ID of the validation period being ended. + * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. If no uptime proof is provided, + * the latest known uptime will be used. + * @param messageIndex The index of the ICM message to be received providing the uptime proof. + */ + function forceInitiateValidatorRemoval( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) external; + + /** + * @notice Completes validator removal by dispatching to the IValidatorManager to update the validator status, + * and unlocking stake. + * + * @param messageIndex The index of the ICM message to be received providing the acknowledgement from the P-Chain. + * This is forwarded to the IValidatorManager to be parsed. + * @return The ID of the validator that was removed. + */ + function completeValidatorRemoval( + uint32 messageIndex + ) external returns (bytes32); + + /** + * @notice Completes the delegator registration process by submitting an acknowledgement of the registration of a + * validationID from the P-Chain. + * Any P-Chain acknowledgement with a nonce greater than or equal to the nonce used to initiate registration of the + * delegator is valid, as long as that nonce has been sent by the contract. For the purposes of computing delegation rewards, + * the delegation is considered active after this function is completed. + * Note: Only the specified delegation will be marked as registered, even if the validator weight update + * message implicitly includes multiple weight changes. + * @param delegationID The ID of the delegation being registered. + * @param messageIndex The index of the ICM message to be received providing the acknowledgement. + */ + function completeDelegatorRegistration(bytes32 delegationID, uint32 messageIndex) external; + + /** + * @notice Begins the process of removing a delegator from a validation period, and reverts if the delegation is not eligible for rewards. + * The delegator must have been previously registered with the given validationID. For the purposes of computing delegation rewards, + * the delegation period is considered ended when this function is called. Uses the supplied uptime proof to calculate rewards. + * If none is provided in the call, the latest known uptime will be used. Reverts if the uptime is not eligible for rewards. + * Note: This function can only be called by the address that registered the delegation. + * Note: Reverts if the uptime is not eligible for rewards. + * @param delegationID The ID of the delegation being removed. + * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. + * If the validator has completed its validation period, it has already provided an uptime proof, so {includeUptimeProof} + * will be ignored and can be set to false. If the validator has not completed its validation period and no uptime proof + * is provided, the latest known uptime will be used. + * @param messageIndex If {includeUptimeProof} is true, the index of the ICM message to be received providing the + * uptime proof. + */ + function initiateDelegatorRemoval( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) external; + + /** + * @notice Begins the process of removing a delegator from a validation period, but does not revert if the delegation is not eligible for rewards. + * The delegator must have been previously registered with the given validationID. For the purposes of computing delegation rewards, + * the delegation period is considered ended when this function is called. Uses the supplied uptime proof to calculate rewards. + * If none is provided in the call, the latest known uptime will be used. Reverts if the uptime is not eligible for rewards. + * Note: This function can only be called by the address that registered the delegation. + * @param delegationID The ID of the delegation being removed. + * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. + * If the validator has completed its validation period, it has already provided an uptime proof, so {includeUptimeProof} + * will be ignored and can be set to false. If the validator has not completed its validation period and no uptime proof + * is provided, the latest known uptime will be used. + * @param messageIndex If {includeUptimeProof} is true, the index of the ICM message to be received providing the + * uptime proof. + */ + function forceInitiateDelegatorRemoval( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) external; + + /** + * @notice Resubmits a delegator registration or delegator end message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param delegationID The ID of the delegation. + */ + function resendUpdateDelegator( + bytes32 delegationID + ) external; + + /** + * @notice Completes the process of ending a delegation by receiving an acknowledgement from the P-Chain. + * Any P-Chain acknowledgement with a nonce greater than or equal to the nonce used to initiate the end of the + * delegator's delegation is valid, as long as that nonce has been sent by the contract. This is because the validator + * weight change pertaining to the delegation ending is included in any subsequent validator weight update messages. + * Note: Only the specified delegation will be marked as completed, even if the validator weight update + * message implicitly includes multiple weight changes. + * @param delegationID The ID of the delegation being removed. + * @param messageIndex The index of the ICM message to be received providing the acknowledgement. + */ + function completeDelegatorRemoval(bytes32 delegationID, uint32 messageIndex) external; + + /** + * @notice Withdraws the delegation fees from completed delegations to the owner of the validator. + * @param validationID The ID of the validation period being ended. + */ + function claimDelegationFees( + bytes32 validationID + ) external; + + /** + * @notice Changes the address of the recipient of the validator's rewards for a validation period. + * @param validationID The ID of the validation period being ended. + * @param recipient The address to receive the rewards. + */ + function changeValidatorRewardRecipient(bytes32 validationID, address recipient) external; + + /** + * @notice Changes the address of the recipient of the delegator's rewards for a delegation period. + * @param delegationID The ID of the validation period being ended. + * @param recipient The address to receive the rewards. + */ + function changeDelegatorRewardRecipient(bytes32 delegationID, address recipient) external; +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IValidatorManager.sol b/icm-contracts/contracts/validator-manager/interfaces/IValidatorManager.sol new file mode 100644 index 000000000..987dd7f8d --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IValidatorManager.sol @@ -0,0 +1,89 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {PChainOwner, ValidatorStatus, IACP99Manager} from "./IACP99Manager.sol"; + +/** + * @dev Validator Manager interface that provides additional functionality on top of {IACP99Manager} + * + * @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md + */ +interface IValidatorManager is IACP99Manager { + error InvalidValidatorManagerAddress(address validatorManagerAddress); + error InvalidWarpOriginSenderAddress(address senderAddress); + error InvalidValidatorManagerBlockchainID(bytes32 blockchainID); + error InvalidWarpSourceChainID(bytes32 sourceChainID); + error InvalidInitializationStatus(); + error InvalidMaximumChurnPercentage(uint8 maximumChurnPercentage); + error InvalidChurnPeriodLength(uint64 churnPeriodLength); + error InvalidBLSKeyLength(uint256 length); + error InvalidNodeID(bytes nodeID); + error InvalidConversionID(bytes32 encodedConversionID, bytes32 expectedConversionID); + error InvalidTotalWeight(uint64 weight); + error InvalidValidationID(bytes32 validationID); + error InvalidValidatorStatus(ValidatorStatus status); + error InvalidNonce(uint64 nonce); + error InvalidWarpMessage(); + error MaxChurnRateExceeded(uint64 churnAmount); + error NodeAlreadyRegistered(bytes nodeID); + error UnexpectedRegistrationStatus(bool validRegistration); + error InvalidPChainOwnerThreshold(uint256 threshold, uint256 addressesLength); + error InvalidPChainOwnerAddresses(); + error ZeroAddress(); + + /** + * @notice Migrates a validator from the V1 contract to the V2 contract. + * @param validationID The ID of the validation period to migrate. + * @param receivedNonce The latest nonce received from the P-Chain. + */ + function migrateFromV1(bytes32 validationID, uint32 receivedNonce) external; + + function initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) external returns (bytes32); + + /** + * @notice Resubmits a validator registration message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param validationID The ID of the validation period being registered. + */ + function resendRegisterValidatorMessage( + bytes32 validationID + ) external; + + function initiateValidatorRemoval( + bytes32 validationID + ) external; + + /** + * @notice Resubmits a validator removal message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param validationID The ID of the validation period being ended. + */ + function resendValidatorRemovalMessage( + bytes32 validationID + ) external; + + function initiateValidatorWeightUpdate( + bytes32 validationID, + uint64 newWeight + ) external returns (uint64, bytes32); + + /** + * @notice Returns a validation ID registered to the given nodeID + * @param nodeID ID of the node associated with the validation ID + */ + function getNodeValidationID( + bytes calldata nodeID + ) external view returns (bytes32); + + function getChurnPeriodSeconds() external view returns (uint64); +} diff --git a/icm-contracts/contracts/validator-manager/interfaces/IValidatorManagerExternalOwnable.sol b/icm-contracts/contracts/validator-manager/interfaces/IValidatorManagerExternalOwnable.sol new file mode 100644 index 000000000..4430bef04 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/interfaces/IValidatorManagerExternalOwnable.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: LicenseRef-Ecosystem +pragma solidity 0.8.25; + +import {IValidatorManager} from "./IValidatorManager.sol"; + +/** + * @notice Combines the {IValidatorManager} interface with the external ownership transfer function from {Ownable}. + * @dev This interface is intended for contracts that need to interact with both validator management and ownership transfer + * without importing both {IValidatorManager} and {Ownable} separately. Note that {Ownable} is a contract, not an interface, + * so this interface only exposes the external ownership transfer method ({transferOwnership}) for convenience. + */ +interface IValidatorManagerExternalOwnable is IValidatorManager { + /** + * @notice Transfers ownership of the validator manager to a new owner. + * @param newOwner The address of the new owner. + * @dev This function can only be called by the current owner. + */ + function transferOwnership( + address newOwner + ) external; +} diff --git a/icm-contracts/contracts/validator-manager/tests/ERC20TokenStakingManagerTests.t.sol b/icm-contracts/contracts/validator-manager/tests/ERC20TokenStakingManagerTests.t.sol new file mode 100644 index 000000000..66f8c75a6 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/ERC20TokenStakingManagerTests.t.sol @@ -0,0 +1,342 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {StakingManagerTest} from "./StakingManagerTests.t.sol"; +import {ERC20TokenStakingManager} from "../ERC20TokenStakingManager.sol"; +import {StakingManager, StakingManagerSettings} from "../StakingManager.sol"; +import {ExampleRewardCalculator} from "../ExampleRewardCalculator.sol"; +import {ICMInitializable} from "../../utilities/ICMInitializable.sol"; +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {IERC20Mintable} from "../interfaces/IERC20Mintable.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; +import {ValidatorManagerTest} from "./ValidatorManagerTests.t.sol"; +import {IACP99Manager, PChainOwner, ConversionData} from "../interfaces/IACP99Manager.sol"; +import {ValidatorManager} from "../ValidatorManager.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; + +contract ERC20TokenStakingManagerTest is StakingManagerTest { + using SafeERC20 for IERC20Mintable; + + ERC20TokenStakingManager public app; + IERC20Mintable public token; + + function setUp() public override { + ValidatorManagerTest.setUp(); + + _setUp(); + _mockGetBlockchainID(); + + ConversionData memory conversion = _defaultConversionData(); + bytes32 conversionID = sha256(ValidatorMessages.packConversionData(conversion)); + _mockInitializeValidatorSet(conversionID); + validatorManager.initializeValidatorSet(conversion, 0); + } + + // + // Initialization unit tests + // The pattern in these tests requires that only non-admin validator manager functions are called, + // as each test re-deploys the ERC20TokenStakingManager contract. + // + function testDisableInitialization() public { + app = new ERC20TokenStakingManager(ICMInitializable.Disallowed); + vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + app.initialize(defaultPoSSettings, token); + } + + function testZeroTokenAddress() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.ZeroAddress.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + app.initialize(defaultPoSSettings, IERC20Mintable(address(0))); + } + + function testZeroRewardCalculatorAddress() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.ZeroAddress.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + app.initialize(defaultPoSSettings, token); + } + + function testZeroManagerddress() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.ZeroAddress.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.rewardCalculator = rewardCalculator; + app.initialize(defaultPoSSettings, token); + } + + function testZeroMinimumDelegationFee() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.InvalidDelegationFee.selector, 0)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumDelegationFeeBips = 0; + app.initialize(defaultPoSSettings, token); + } + + function testMaxMinimumDelegationFee() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + uint16 minimumDelegationFeeBips = app.MAXIMUM_DELEGATION_FEE_BIPS() + 1; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidDelegationFee.selector, minimumDelegationFeeBips + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumDelegationFeeBips = minimumDelegationFeeBips; + app.initialize(defaultPoSSettings, token); + } + + function testInvalidStakeAmountRange() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidStakeAmount.selector, DEFAULT_MAXIMUM_STAKE_AMOUNT + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumStakeAmount = DEFAULT_MAXIMUM_STAKE_AMOUNT; + defaultPoSSettings.maximumStakeAmount = DEFAULT_MINIMUM_STAKE_AMOUNT; + app.initialize(defaultPoSSettings, token); + } + + function testZeroMaxStakeMultiplier() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.InvalidStakeMultiplier.selector, 0)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.maximumStakeMultiplier = 0; + app.initialize(defaultPoSSettings, token); + } + + function testMinStakeDurationTooLow() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + uint64 minimumStakeDuration = DEFAULT_CHURN_PERIOD - 1; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidMinStakeDuration.selector, minimumStakeDuration + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumStakeDuration = minimumStakeDuration; + app.initialize(defaultPoSSettings, token); + } + + function testMaxStakeMultiplierOverLimit() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + uint8 maximumStakeMultiplier = app.MAXIMUM_STAKE_MULTIPLIER_LIMIT() + 1; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidStakeMultiplier.selector, maximumStakeMultiplier + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.maximumStakeMultiplier = maximumStakeMultiplier; + app.initialize(defaultPoSSettings, token); + } + + function testZeroWeightToValueFactor() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.ZeroWeightToValueFactor.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.weightToValueFactor = 0; + app.initialize(defaultPoSSettings, token); + } + + function testInvalidValidatorManager() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + ValidatorManager invalidManager = ValidatorManager(address(token)); // The contract type is arbitrary + + vm.expectRevert(); + + StakingManagerSettings memory settings = _defaultPoSSettings(); + settings.manager = invalidManager; + app.initialize(settings, token); + } + + function testUnsetValidatorManager() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(); + + app.initialize(_defaultPoSSettings(), token); // settings.manager is not set + } + + function testInvalidValidatorMinStakeDuration() public { + uint256 stakeAmount = _weightToValue(DEFAULT_WEIGHT); + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidMinStakeDuration.selector, DEFAULT_MINIMUM_STAKE_DURATION - 1 + ) + ); + app.initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION - 1, + stakeAmount: stakeAmount, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + } + + function testERC20TokenStakingManagerStorageSlot() public view { + assertEq( + _erc7201StorageSlot("ERC20TokenStakingManager"), + app.ERC20_STAKING_MANAGER_STORAGE_LOCATION() + ); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight, + address rewardRecipient + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + stakeAmount: _weightToValue(weight), + rewardRecipient: rewardRecipient + }); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount, + address rewardRecipient + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: delegationFeeBips, + minStakeDuration: minStakeDuration, + stakeAmount: stakeAmount, + rewardRecipient: rewardRecipient + }); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + stakeAmount: _weightToValue(weight), + rewardRecipient: address(this) + }); + } + + function _initiateDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight, + address rewardRecipient + ) internal virtual override returns (bytes32) { + uint256 value = _weightToValue(weight); + vm.startPrank(delegatorAddress); + bytes32 delegationID = + app.initiateDelegatorRegistration(validationID, value, rewardRecipient); + vm.stopPrank(); + return delegationID; + } + + function _beforeSend(uint256 amount, address spender) internal override { + token.safeIncreaseAllowance(spender, amount); + token.safeTransfer(spender, amount); + + // ERC20 tokens need to be pre-approved + vm.startPrank(spender); + token.safeIncreaseAllowance(address(app), amount); + vm.stopPrank(); + } + + function _expectStakeUnlock(address account, uint256 amount) internal override { + vm.expectCall(address(token), abi.encodeCall(IERC20.transfer, (account, amount))); + } + + function _expectRewardIssuance(address account, uint256 amount) internal override { + vm.expectCall(address(token), abi.encodeCall(IERC20Mintable.mint, (account, amount))); + } + + function _setUp() internal override returns (IACP99Manager) { + // Construct the object under test + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + token = new ExampleERC20(); + rewardCalculator = new ExampleRewardCalculator(DEFAULT_REWARD_RATE); + validatorManager = new ValidatorManager(ICMInitializable.Allowed); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.manager = validatorManager; + + validatorManager.initialize(_defaultSettings(address(app))); + app.initialize(defaultPoSSettings, token); + + stakingManager = app; + + return validatorManager; + } + + function _getStakeAssetBalance( + address account + ) internal view override returns (uint256) { + return token.balanceOf(account); + } +} diff --git a/icm-contracts/contracts/validator-manager/tests/ExamplesRewardCalculatorTests.t.sol b/icm-contracts/contracts/validator-manager/tests/ExamplesRewardCalculatorTests.t.sol new file mode 100644 index 000000000..02ea48247 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/ExamplesRewardCalculatorTests.t.sol @@ -0,0 +1,46 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ExampleRewardCalculator} from "../ExampleRewardCalculator.sol"; +import {IRewardCalculator} from "../interfaces/IRewardCalculator.sol"; + +contract ExampleRewardCalculatorTest is Test { + uint256 public constant DEFAULT_STAKE_AMOUNT = 1e12; + uint64 public constant DEFAULT_START_TIME = 1000; + uint64 public constant DEFAULT_END_TIME = 31537000; // a year + 1000 seonds + uint64 public constant DEFAULT_UPTIME = (DEFAULT_END_TIME - DEFAULT_START_TIME) * 80 / 100; + uint64 public constant DEFAULT_REWARD_BASIS_POINTS = 42; + + IRewardCalculator public exampleRewardCalculator; + + function setUp() public { + exampleRewardCalculator = new ExampleRewardCalculator(DEFAULT_REWARD_BASIS_POINTS); + } + + function testRewardCalculation() public view { + uint256 output = exampleRewardCalculator.calculateReward({ + stakeAmount: DEFAULT_STAKE_AMOUNT, + validatorStartTime: DEFAULT_START_TIME, + stakingStartTime: DEFAULT_START_TIME, + stakingEndTime: DEFAULT_END_TIME, + uptimeSeconds: DEFAULT_UPTIME + }); + assertEq(output, 42e8); + } + + function testInsufficientUptime() public view { + uint256 output = exampleRewardCalculator.calculateReward({ + stakeAmount: DEFAULT_STAKE_AMOUNT, + validatorStartTime: DEFAULT_START_TIME, + stakingStartTime: DEFAULT_START_TIME, + stakingEndTime: DEFAULT_END_TIME, + uptimeSeconds: DEFAULT_UPTIME - 1 + }); + assertEq(output, 0); + } +} diff --git a/icm-contracts/contracts/validator-manager/tests/NativeTokenStakingManagerTests.t.sol b/icm-contracts/contracts/validator-manager/tests/NativeTokenStakingManagerTests.t.sol new file mode 100644 index 000000000..c1ca39131 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/NativeTokenStakingManagerTests.t.sol @@ -0,0 +1,302 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {StakingManagerTest} from "./StakingManagerTests.t.sol"; +import {NativeTokenStakingManager} from "../NativeTokenStakingManager.sol"; +import {StakingManager, StakingManagerSettings} from "../StakingManager.sol"; +import {ExampleRewardCalculator} from "../ExampleRewardCalculator.sol"; +import {ICMInitializable} from "../../utilities/ICMInitializable.sol"; +import {INativeMinter} from "@subnet-evm/INativeMinter.sol"; +import {ValidatorManagerTest} from "./ValidatorManagerTests.t.sol"; +import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; +import {IACP99Manager, PChainOwner, ConversionData} from "../interfaces/IACP99Manager.sol"; +import {ValidatorManager} from "../ValidatorManager.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; + +contract NativeTokenStakingManagerTest is StakingManagerTest { + NativeTokenStakingManager public app; + + function setUp() public override { + ValidatorManagerTest.setUp(); + + _setUp(); + _mockGetBlockchainID(); + + ConversionData memory conversion = _defaultConversionData(); + bytes32 conversionID = sha256(ValidatorMessages.packConversionData(conversion)); + _mockInitializeValidatorSet(conversionID); + validatorManager.initializeValidatorSet(conversion, 0); + } + + // + // Initialization unit tests + // The pattern in these tests requires that only non-admin validator manager functions are called, + // as each test re-deploys the NativeTokenStakingManager contract. + // + function testDisableInitialization() public { + app = new NativeTokenStakingManager(ICMInitializable.Disallowed); + vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + app.initialize(defaultPoSSettings); + } + + function testZeroMinimumDelegationFee() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.InvalidDelegationFee.selector, 0)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumDelegationFeeBips = 0; + app.initialize(defaultPoSSettings); + } + + function testMaxMinimumDelegationFee() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + uint16 minimumDelegationFeeBips = app.MAXIMUM_DELEGATION_FEE_BIPS() + 1; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidDelegationFee.selector, minimumDelegationFeeBips + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumDelegationFeeBips = minimumDelegationFeeBips; + app.initialize(defaultPoSSettings); + } + + function testInvalidStakeAmountRange() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidStakeAmount.selector, DEFAULT_MAXIMUM_STAKE_AMOUNT + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumStakeAmount = DEFAULT_MAXIMUM_STAKE_AMOUNT; + defaultPoSSettings.maximumStakeAmount = DEFAULT_MINIMUM_STAKE_AMOUNT; + app.initialize(defaultPoSSettings); + } + + function testZeroMaxStakeMultiplier() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.InvalidStakeMultiplier.selector, 0)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.maximumStakeMultiplier = 0; + app.initialize(defaultPoSSettings); + } + + function testMaxStakeMultiplierOverLimit() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + uint8 maximumStakeMultiplier = app.MAXIMUM_STAKE_MULTIPLIER_LIMIT() + 1; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidStakeMultiplier.selector, maximumStakeMultiplier + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.maximumStakeMultiplier = maximumStakeMultiplier; + app.initialize(defaultPoSSettings); + } + + function testZeroWeightToValueFactor() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.ZeroWeightToValueFactor.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.weightToValueFactor = 0; + app.initialize(defaultPoSSettings); + } + + function testMinStakeDurationTooLow() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + uint64 minStakeDuration = DEFAULT_CHURN_PERIOD - 1; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidMinStakeDuration.selector, minStakeDuration + ) + ); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.minimumStakeDuration = minStakeDuration; + app.initialize(defaultPoSSettings); + } + + function testInvalidValidatorManager() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + TestableNativeTokenStakingManager invalidManager = + new TestableNativeTokenStakingManager(ICMInitializable.Allowed); // the contract type is arbitrary + + vm.expectRevert(); + + StakingManagerSettings memory settings = _defaultPoSSettings(); + settings.manager = ValidatorManager(address(invalidManager)); + app.initialize(settings); + } + + function testZeroRewardCalculatorAddress() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.ZeroAddress.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.manager = validatorManager; + app.initialize(defaultPoSSettings); + } + + function testZeroManagerddress() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(abi.encodeWithSelector(StakingManager.ZeroAddress.selector)); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.rewardCalculator = rewardCalculator; + app.initialize(defaultPoSSettings); + } + + // Helpers + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount, + address rewardRecipient + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration{value: stakeAmount}({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: delegationFeeBips, + minStakeDuration: minStakeDuration, + rewardRecipient: rewardRecipient + }); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight, + address rewardRecipient + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration{value: _weightToValue(weight)}({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + rewardRecipient: rewardRecipient + }); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration{value: _weightToValue(weight)}({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + rewardRecipient: address(this) + }); + } + + function _initiateDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight, + address rewardRecipient + ) internal virtual override returns (bytes32) { + uint256 value = _weightToValue(weight); + vm.prank(delegatorAddress); + vm.deal(delegatorAddress, value); + return app.initiateDelegatorRegistration{value: value}(validationID, rewardRecipient); + } + + // solhint-disable no-empty-blocks + function _beforeSend(uint256 amount, address spender) internal override { + // Native tokens no need pre approve + } + // solhint-enable no-empty-blocks + + function _expectStakeUnlock(address account, uint256 amount) internal override { + // empty calldata implies the receive function will be called + vm.expectCall(account, amount, ""); + } + + function _expectRewardIssuance(address account, uint256 amount) internal override { + address nativeMinter = address(app.NATIVE_MINTER()); + bytes memory callData = abi.encodeCall(INativeMinter.mintNativeCoin, (account, amount)); + vm.mockCall(nativeMinter, callData, ""); + vm.expectCall(nativeMinter, callData); + } + + function _setUp() internal override returns (IACP99Manager) { + // Construct the object under test + app = new TestableNativeTokenStakingManager(ICMInitializable.Allowed); + rewardCalculator = new ExampleRewardCalculator(DEFAULT_REWARD_RATE); + validatorManager = new ValidatorManager(ICMInitializable.Allowed); + + StakingManagerSettings memory defaultPoSSettings = _defaultPoSSettings(); + defaultPoSSettings.rewardCalculator = rewardCalculator; + defaultPoSSettings.manager = validatorManager; + + validatorManager.initialize(_defaultSettings(address(app))); + app.initialize(defaultPoSSettings); + + stakingManager = app; + + return validatorManager; + } + + function _getStakeAssetBalance( + address account + ) internal view override returns (uint256) { + return account.balance; + } +} + +contract TestableNativeTokenStakingManager is NativeTokenStakingManager, Test { + constructor( + ICMInitializable init + ) NativeTokenStakingManager(init) {} + + function _reward(address account, uint256 amount) internal virtual override { + super._reward(account, amount); + // Units tests don't have access to the native minter precompile, so use vm.deal instead. + vm.deal(account, account.balance + amount); + } +} diff --git a/icm-contracts/contracts/validator-manager/tests/PoAManagerTests.t.sol b/icm-contracts/contracts/validator-manager/tests/PoAManagerTests.t.sol new file mode 100644 index 000000000..7175831c2 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/PoAManagerTests.t.sol @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: LicenseRef-Ecosystem +pragma solidity 0.8.25; + +import {ValidatorManagerTest} from "./ValidatorManagerTests.t.sol"; +import {PoAManager} from "../PoAManager.sol"; +import {ValidatorManager, ValidatorManagerSettings} from "../ValidatorManager.sol"; +import {IValidatorManagerExternalOwnable} from "../interfaces/IValidatorManagerExternalOwnable.sol"; +import {IACP99Manager, PChainOwner, ConversionData} from "../interfaces/IACP99Manager.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; + +contract PoAManagerTest is ValidatorManagerTest { + PoAManager public poaManager; + + function setUp() public override { + ValidatorManagerTest.setUp(); + + _setUp(); + _mockGetBlockchainID(); + + ConversionData memory conversion = _defaultConversionData(); + bytes32 conversionID = sha256(ValidatorMessages.packConversionData(conversion)); + _mockInitializeValidatorSet(conversionID); + validatorManager.initializeValidatorSet(conversion, 0); + } + + function testOnlyOwnerCanInitiateValidatorRegistration() public { + vm.prank(vm.addr(1)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, vm.addr(1) + ) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testAnyoneCanCompleteValidatorRegistration() public { + bytes32 validationID = _setUpInitiateValidatorRegistration( + DEFAULT_NODE_ID, + DEFAULT_SUBNET_ID, + DEFAULT_WEIGHT, + DEFAULT_BLS_PUBLIC_KEY, + address(this) + ); + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, true); + + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorRegistration(validationID, DEFAULT_WEIGHT); + + vm.prank(vm.addr(1)); + _completeValidatorRegistration(0); + } + + function testOnlyOwnerCanInitiateValidatorRemoval() public { + bytes32 validationID = _registerDefaultValidator(); + + vm.prank(vm.addr(1)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, vm.addr(1) + ) + ); + _initiateValidatorRemoval(validationID, false); + } + + function testAnyoneCanCompleteValidatorRemoval() public { + bytes32 validationID = _registerDefaultValidator(); + _initiateValidatorRemoval(validationID, false); + + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, false); + + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorRemoval(validationID); + + vm.prank(vm.addr(1)); + _completeValidatorRemoval(0); + } + + function testOnlyOwnerCanInitiateValidatorWeightUpdate() public { + vm.prank(vm.addr(1)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, vm.addr(1) + ) + ); + poaManager.initiateValidatorWeightUpdate(bytes32(0), 0); + } + + function testAnyoneCanCompleteValidatorWeightUpdate() public { + bytes32 validationID = _registerDefaultValidator(); + uint64 newWeight = DEFAULT_WEIGHT + 1; + + poaManager.initiateValidatorWeightUpdate(validationID, newWeight); + + bytes memory l1ValidatorWeightUpdateMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 0, newWeight); + + _mockGetPChainWarpMessage(l1ValidatorWeightUpdateMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorWeightUpdate(validationID, 0, newWeight); + + vm.prank(vm.addr(1)); + poaManager.completeValidatorWeightUpdate(0); + } + + function testPoAMangerOnlyOwnerCanTransferOwnership() public { + address newOwner = vm.addr(1); + poaManager.transferValidatorManagerOwnership(newOwner); + + assertEq(validatorManager.owner(), newOwner, "Ownership should be transferred"); + } + + function testPoAMangerFailedTransferOwnership() public { + address newOwner = vm.addr(1); + vm.prank(newOwner); + vm.expectRevert( + abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, newOwner) + ); + poaManager.transferValidatorManagerOwnership(newOwner); + } + + function testPoAManagerIsOwnerOfValidatorManager() public view { + assertEq(validatorManager.owner(), address(poaManager), "PoAManager should be owner"); + } + + function _setUp() internal override returns (IACP99Manager) { + validatorManager = new ValidatorManager(ICMInitializable.Allowed); + poaManager = new PoAManager( + address(this), IValidatorManagerExternalOwnable(address(validatorManager)) + ); + + // Construct ValidatorManagerSettings with the correct fields + ValidatorManagerSettings memory settings = _defaultSettings(address(poaManager)); + + validatorManager.initialize(settings); + return validatorManager; + } + + // Implement required abstract functions + // solhint-disable-next-line no-empty-blocks + function _beforeSend(uint256 amount, address spender) internal virtual override {} + + function _beforeRegisterValidator( + bytes32 validationID, + address rewardRecipient + ) internal virtual override + // solhint-disable-next-line no-empty-blocks + {} + + // Override helper functions to call PoAManager instead of ValidatorManager + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight, + address /*rewardRecipient*/ + ) internal virtual override returns (bytes32) { + return poaManager.initiateValidatorRegistration( + nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight + ); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) internal virtual override returns (bytes32) { + return poaManager.initiateValidatorRegistration( + nodeID, blsPublicKey, remainingBalanceOwner, disableOwner, weight + ); + } + + function _completeValidatorRegistration( + uint32 messageIndex + ) internal virtual override returns (bytes32) { + return poaManager.completeValidatorRegistration(messageIndex); + } + + function _initiateValidatorRemoval( + bytes32 validationID, + bool /*includeUptime*/ + ) internal virtual override { + poaManager.initiateValidatorRemoval(validationID); + } + + function _forceInitiateValidatorRemoval( + bytes32 validationID, + bool /*includeUptime*/ + ) internal virtual override { + poaManager.initiateValidatorRemoval(validationID); + } + + function _completeValidatorRemoval( + uint32 messageIndex + ) internal virtual override returns (bytes32) { + return poaManager.completeValidatorRemoval(messageIndex); + } +} diff --git a/icm-contracts/contracts/validator-manager/tests/PoAValidatorManagerTests.t.sol b/icm-contracts/contracts/validator-manager/tests/PoAValidatorManagerTests.t.sol new file mode 100644 index 000000000..32c4515ab --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/PoAValidatorManagerTests.t.sol @@ -0,0 +1,146 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {ValidatorManagerTest} from "./ValidatorManagerTests.t.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts@5.0.2/proxy/utils/Initializable.sol"; +import {IACP99Manager, PChainOwner, ConversionData} from "../interfaces/IACP99Manager.sol"; +import {IValidatorManager, ValidatorManager} from "../ValidatorManager.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; + +contract PoAValidatorManagerTest is ValidatorManagerTest { + address public constant DEFAULT_OWNER = address(0x1); + + ValidatorManager public app; + + function setUp() public override { + ValidatorManagerTest.setUp(); + + _setUp(); + _mockGetBlockchainID(); + + ConversionData memory conversion = _defaultConversionData(); + bytes32 conversionID = sha256(ValidatorMessages.packConversionData(conversion)); + _mockInitializeValidatorSet(conversionID); + validatorManager.initializeValidatorSet(conversion, 0); + } + + function testDisableInitialization() public { + app = new ValidatorManager(ICMInitializable.Disallowed); + vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + app.initialize(_defaultSettings(address(this))); + } + + function testInvalidOwnerRegistration() public { + vm.prank(vm.addr(1)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, vm.addr(1) + ) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + // This test applies to all ValidatorManagers, but we test it here to avoid + // having to source UINT64MAX funds for StakingManagers. + function testTotalWeightOverflow() public { + uint64 weight = type(uint64).max; + + bytes memory nodeID = _newNodeID(); + vm.expectRevert( + abi.encodeWithSelector(IValidatorManager.InvalidTotalWeight.selector, weight) + ); + + _initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: weight + }); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + weight: weight + }); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight, + address + ) internal virtual override returns (bytes32) { + return app.initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: remainingBalanceOwner, + disableOwner: disableOwner, + weight: weight + }); + } + + function _completeValidatorRegistration( + uint32 messageIndex + ) internal virtual override returns (bytes32) { + return app.completeValidatorRegistration(messageIndex); + } + + function _initiateValidatorRemoval(bytes32 validationID, bool) internal virtual override { + return app.initiateValidatorRemoval(validationID); + } + + function _forceInitiateValidatorRemoval(bytes32 validationID, bool) internal virtual override { + return app.initiateValidatorRemoval(validationID); + } + + function _completeValidatorRemoval( + uint32 messageIndex + ) internal virtual override returns (bytes32) { + return app.completeValidatorRemoval(messageIndex); + } + + function _setUp() internal override returns (IACP99Manager) { + validatorManager = new ValidatorManager(ICMInitializable.Allowed); + app = validatorManager; + + validatorManager.initialize(_defaultSettings(address(this))); + + return validatorManager; + } + + // solhint-disable-next-line no-empty-blocks + function _beforeSend(uint256 amount, address spender) internal virtual override {} + + function _beforeRegisterValidator( + bytes32 validationID, + address rewardRecipient + ) internal virtual override + // solhint-disable-next-line no-empty-blocks + {} +} diff --git a/icm-contracts/contracts/validator-manager/tests/StakingManagerTests.t.sol b/icm-contracts/contracts/validator-manager/tests/StakingManagerTests.t.sol new file mode 100644 index 000000000..d2d141e6c --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/StakingManagerTests.t.sol @@ -0,0 +1,2703 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {IRewardCalculator} from "../interfaces/IRewardCalculator.sol"; +import {ValidatorManagerTest} from "./ValidatorManagerTests.t.sol"; +import {StakingManager} from "../StakingManager.sol"; +import {DelegatorStatus, StakingManagerSettings} from "../interfaces/IStakingManager.sol"; +import {IValidatorManager, ValidatorManager, ValidatorStatus} from "../ValidatorManager.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; +import {WarpMessage, IWarpMessenger} from "@subnet-evm/IWarpMessenger.sol"; +import {PChainOwner} from "../ACP99Manager.sol"; + +abstract contract StakingManagerTest is ValidatorManagerTest { + uint64 public constant DEFAULT_UPTIME = uint64(100); + uint64 public constant DEFAULT_DELEGATOR_WEIGHT = uint64(1e5); + uint64 public constant DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP = + DEFAULT_REGISTRATION_TIMESTAMP + 1000; + uint64 public constant DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP = + DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1000; + uint64 public constant DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP = + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION; + address public constant DEFAULT_DELEGATOR_ADDRESS = + address(0x1234123412341234123412341234123412341234); + address public constant DEFAULT_VALIDATOR_OWNER_ADDRESS = + address(0x2345234523452345234523452345234523452345); + uint64 public constant DEFAULT_REWARD_RATE = uint64(10); + uint64 public constant DEFAULT_MINIMUM_STAKE_DURATION = 24 hours; + uint16 public constant DEFAULT_MINIMUM_DELEGATION_FEE_BIPS = 100; + uint16 public constant DEFAULT_DELEGATION_FEE_BIPS = 150; + uint8 public constant DEFAULT_MAXIMUM_STAKE_MULTIPLIER = 4; + uint256 public constant DEFAULT_WEIGHT_TO_VALUE_FACTOR = 1e12; + uint256 public constant SECONDS_IN_YEAR = 31536000; + + StakingManager public stakingManager; + IRewardCalculator public rewardCalculator; + + event InitiatedDelegatorRegistration( + bytes32 indexed delegationID, + bytes32 indexed validationID, + address indexed delegatorAddress, + uint64 nonce, + uint64 validatorWeight, + uint64 delegatorWeight, + bytes32 setWeightMessageID, + address rewardRecipient + ); + + event InitiatedStakingValidatorRegistration( + bytes32 indexed validationID, + address indexed owner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + address rewardRecipient + ); + + event CompletedDelegatorRegistration( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 startTime + ); + + event InitiatedDelegatorRemoval(bytes32 indexed delegationID, bytes32 indexed validationID); + + event CompletedDelegatorRemoval( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees + ); + + event UptimeUpdated(bytes32 indexed validationID, uint64 uptime); + + event ValidatorRewardClaimed( + bytes32 indexed validationID, address indexed recipient, uint256 amount + ); + + event ValidatorRewardRecipientChanged( + bytes32 indexed validationID, address indexed recipient, address indexed oldRecipient + ); + + event DelegatorRewardClaimed( + bytes32 indexed delegationID, address indexed recipient, uint256 amount + ); + + event DelegatorRewardRecipientChanged( + bytes32 indexed delegationID, address indexed recipient, address indexed oldRecipient + ); + + function testDelegationFeeBipsTooLow() public { + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidDelegationFee.selector, + DEFAULT_MINIMUM_DELEGATION_FEE_BIPS - 1 + ) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + delegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS - 1, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + stakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + rewardRecipient: address(this) + }); + } + + function testDelegationFeeBipsTooHigh() public { + uint16 delegationFeeBips = stakingManager.MAXIMUM_DELEGATION_FEE_BIPS() + 1; + vm.expectRevert( + abi.encodeWithSelector(StakingManager.InvalidDelegationFee.selector, delegationFeeBips) + ); + + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + delegationFeeBips: delegationFeeBips, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + stakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + rewardRecipient: address(this) + }); + } + + function testInvalidMinStakeDuration() public { + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidMinStakeDuration.selector, DEFAULT_MINIMUM_STAKE_DURATION - 1 + ) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION - 1, + stakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + rewardRecipient: address(this) + }); + } + + function testStakeAmountTooLow() public { + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidStakeAmount.selector, DEFAULT_MINIMUM_STAKE_AMOUNT - 1 + ) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + stakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT - 1, + rewardRecipient: address(this) + }); + } + + function testStakeAmountTooHigh() public { + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidStakeAmount.selector, DEFAULT_MAXIMUM_STAKE_AMOUNT + 1 + ) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + stakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT + 1, + rewardRecipient: address(this) + }); + } + + function testInvalidInitializeEndTime() public { + bytes32 validationID = _registerDefaultValidator(); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.MinStakeDurationNotPassed.selector, block.timestamp + ) + ); + stakingManager.initiateValidatorRemoval(validationID, false, 0); + } + + function testInvalidUptimeWarpMessage() public { + bytes32 validationID = _registerDefaultValidator(); + + _mockGetUptimeWarpMessage(new bytes(0), false); + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + vm.expectRevert(IValidatorManager.InvalidWarpMessage.selector); + stakingManager.initiateValidatorRemoval(validationID, true, 0); + } + + function testInvalidUptimeSenderAddress() public { + bytes32 validationID = _registerDefaultValidator(); + + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(this), + payload: new bytes(0) + }), + true + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidWarpOriginSenderAddress.selector, address(this) + ) + ); + stakingManager.initiateValidatorRemoval(validationID, true, 0); + } + + function testInvalidUptimeValidationID() public { + bytes32 validationID = _registerDefaultValidator(); + + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(0), + payload: ValidatorMessages.packValidationUptimeMessage(bytes32(0), 0) + }), + true + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.UnexpectedValidationID.selector, bytes32(0), validationID + ) + ); + stakingManager.initiateValidatorRemoval(validationID, true, 0); + } + + function testInvalidRewardRecipient() public { + vm.expectRevert( + abi.encodeWithSelector(StakingManager.InvalidRewardRecipient.selector, address(0)) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + delegationFeeBips: DEFAULT_DELEGATION_FEE_BIPS, + minStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + stakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + rewardRecipient: address(0) + }); + } + + function testInvalidDelegatorRewardRecipient() public { + bytes32 validationID = _registerDefaultValidator(); + _beforeSend(_weightToValue(DEFAULT_DELEGATOR_WEIGHT), DEFAULT_DELEGATOR_ADDRESS); + vm.expectRevert( + abi.encodeWithSelector(StakingManager.InvalidRewardRecipient.selector, address(0)) + ); + _initiateDelegatorRegistration( + validationID, DEFAULT_DELEGATOR_ADDRESS, DEFAULT_DELEGATOR_WEIGHT, address(0) + ); + } + + function testInitiateDelegatorRegistration() public { + bytes32 validationID = _registerDefaultValidator(); + + _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + } + + function testInitiateDelegatorRegistrationInactiveValidator() public { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + address validatorOwner = address(this); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT, + rewardRecipient: validatorOwner + }); + + _beforeSend(_weightToValue(DEFAULT_DELEGATOR_WEIGHT), DEFAULT_DELEGATOR_ADDRESS); + + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.Completed + ) + ); + _initiateDelegatorRegistration( + validationID, + DEFAULT_DELEGATOR_ADDRESS, + DEFAULT_DELEGATOR_WEIGHT, + DEFAULT_DELEGATOR_ADDRESS + ); + } + + function testResendDelegatorRegistration() public { + bytes32 validationID = _registerDefaultValidator(); + + bytes32 delegationID = _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, 1, DEFAULT_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + ); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + stakingManager.resendUpdateDelegator(delegationID); + } + + function testCompleteDelegatorRegistration() public { + bytes32 validationID = _registerDefaultValidator(); + + _registerDefaultDelegator(validationID); + } + + function testCompleteDelegatorRegistrationWrongNonce() public { + bytes32 validationID = _registerDefaultValidator(); + + // Initialize two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + address delegator2 = address(0x5678567856785678567856785678567856785678); + bytes32 delegationID2 = _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + + DEFAULT_WEIGHT, + expectedNonce: 2, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + + // Complete registration of delegator2 with delegator1's nonce + // Note that registering delegator1 with delegator2's nonce is valid + uint64 nonce = 1; + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, nonce, DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT + ); + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + vm.warp(DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP); + vm.expectRevert(abi.encodeWithSelector(IValidatorManager.InvalidNonce.selector, nonce)); + stakingManager.completeDelegatorRegistration(delegationID2, 0); + } + + function testCompleteDelegatorRegistrationImplicitNonce() public { + bytes32 validationID = _registerDefaultValidator(); + + // Initialize two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + bytes32 delegationID1 = _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + address delegator2 = address(0x5678567856785678567856785678567856785678); + _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + + DEFAULT_WEIGHT, + expectedNonce: 2, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + // Mark delegator1 as registered by delivering the weight update from nonce 2 (delegator 2's nonce) + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, 2, DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT + ); + + _setUpCompleteDelegatorRegistration( + delegationID1, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + setValidatorWeightPayload + ); + } + + function testInitiateeEndValidationNotOwner() public { + bytes32 validationID = _registerDefaultValidator(); + + vm.prank(address(1)); + vm.expectRevert( + abi.encodeWithSelector(StakingManager.UnauthorizedOwner.selector, address(1)) + ); + stakingManager.initiateValidatorRemoval(validationID, false, 0); + } + + function testInitiateDelegatorRemoval() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + } + + function testInitiateDelegatorRemovalByValidator() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: address(this), + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + } + + function testInitiateDelegatorRemovalByValidatorMinStakeDurationNotPassed() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + uint64 invalidEndTime = DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1 hours; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.MinStakeDurationNotPassed.selector, invalidEndTime + ) + ); + _initiateDelegatorRemoval({ + sender: address(this), + delegationID: delegationID, + endDelegationTimestamp: invalidEndTime, + includeUptime: false, + force: false + }); + } + + function testInitiateDelegatorRemovalMinStakeDurationNotPassed() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + uint64 invalidEndTime = + DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION - 1; + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.MinStakeDurationNotPassed.selector, invalidEndTime + ) + ); + _initiateDelegatorRemoval({ + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + endDelegationTimestamp: invalidEndTime, + includeUptime: false, + force: false + }); + } + + function testCompleteDelegatorRemovalChurnPeriodSecondsNotPassed() public { + bytes32 validationID = _registerDefaultValidator(); + uint64 delegatorRegistrationTime = + DEFAULT_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION + 1; + bytes32 delegationID = _registerDelegator({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + initRegistrationTimestamp: delegatorRegistrationTime - 1, + completeRegistrationTimestamp: delegatorRegistrationTime, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + + address validatorOwner = address(this); + + _endValidationWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + completeRegistrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: delegatorRegistrationTime + 1, + validatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + rewardRecipient: validatorOwner + }); + + uint64 invalidEndTime = delegatorRegistrationTime + DEFAULT_CHURN_PERIOD - 1; + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.MinStakeDurationNotPassed.selector, invalidEndTime + ) + ); + + // Initialize end delegation will also call _completeDelegatorRemoval because the validator is copmleted. + _initiateDelegatorRemoval({ + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + endDelegationTimestamp: invalidEndTime, + includeUptime: false, + force: false + }); + } + + function testInitiateDelegatorRemovalInsufficientUptime() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.DelegatorIneligibleForRewards.selector, delegationID + ) + ); + vm.warp(DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP); + vm.prank(DEFAULT_DELEGATOR_ADDRESS); + stakingManager.initiateDelegatorRemoval(delegationID, false, 0); + } + + function testForceInitiateDelegatorRemoval() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: true + }); + } + + function testForceInitiateDelegatorRemovalInsufficientUptime() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: false, + force: true + }); + } + + function testResendEndDelegation() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 2, DEFAULT_WEIGHT); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + stakingManager.resendUpdateDelegator(delegationID); + } + + function testResendEndValidation() public override { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + validatorManager.resendValidatorRemovalMessage(validationID); + } + + function testCompleteDelegatorRemoval() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _completeDefaultDelegator(validationID, delegationID); + } + + function testClaimDelegationFeesInvalidValidatorStatus() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _completeDefaultDelegator(validationID, delegationID); + + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.Active + ) + ); + + stakingManager.claimDelegationFees(validationID); + } + + function testClaimDelegationFeesInvalidSender() public { + bytes32 validationID = _registerDefaultValidator(); + _registerDefaultDelegator(validationID); + + _endDefaultValidatorWithChecks(validationID, 2); + + vm.expectRevert( + abi.encodeWithSelector(StakingManager.UnauthorizedOwner.selector, address(123)) + ); + + vm.prank(address(123)); + stakingManager.claimDelegationFees(validationID); + } + + function testClaimDelegationFees() public { + bytes32 validationID = _registerDefaultValidator(); + address rewardRecipient = address(42); + bytes32 delegationID = _registerDefaultDelegatorWithRecipient(validationID, rewardRecipient); + + _endDefaultValidatorWithChecks(validationID, 2); + + // Validator is Completed, so this will also complete the delegation. + _initiateDelegatorRemoval({ + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + includeUptime: true, + force: false + }); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint256 expectedDelegationFee = (expectedTotalReward * DEFAULT_DELEGATION_FEE_BIPS) / 10000; + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit ValidatorRewardClaimed(validationID, address(this), expectedDelegationFee); + _expectRewardIssuance(address(this), expectedDelegationFee); + stakingManager.claimDelegationFees(validationID); + } + + function testClaimDelegationFeesWithRewardRecipient() public { + bytes32 validationID = _registerDefaultValidator(); + address rewardRecipient = address(42); + bytes32 delegationID = _registerDefaultDelegatorWithRecipient(validationID, rewardRecipient); + + _endDefaultValidatorWithChecks(validationID, 2); + + // Validator is Completed, so this will also complete the delegation. + _initiateDelegatorRemoval({ + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + includeUptime: true, + force: false + }); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint256 expectedDelegationFee = (expectedTotalReward * DEFAULT_DELEGATION_FEE_BIPS) / 10000; + + // Change the reward recipient to a different address + address newRewardRecipient = address(43); + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit ValidatorRewardRecipientChanged(validationID, newRewardRecipient, address(this)); + stakingManager.changeValidatorRewardRecipient(validationID, newRewardRecipient); + + // Claim delegation fees should now go to the new reward recipient + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit ValidatorRewardClaimed(validationID, newRewardRecipient, expectedDelegationFee); + _expectRewardIssuance(newRewardRecipient, expectedDelegationFee); + stakingManager.claimDelegationFees(validationID); + } + + function testCompleteDelegatorRemovalWithNonDelegatorRewardRecipient() public { + bytes32 validationID = _registerDefaultValidator(); + address rewardRecipient = address(42); + bytes32 delegationID = _registerDefaultDelegatorWithRecipient(validationID, rewardRecipient); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + uptimeSeconds: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint256 expectedValidatorFees = + _calculateValidatorFeesFromDelegator(expectedTotalReward, DEFAULT_DELEGATION_FEE_BIPS); + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + _completeDelegatorRemovalWithChecks({ + validationID: validationID, + delegationID: delegationID, + delegator: DEFAULT_DELEGATOR_ADDRESS, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedValidatorFees: expectedValidatorFees, + expectedDelegatorReward: expectedDelegatorReward, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + } + + function testChangeDelegatorRewardRecipientWithNullAddress() public { + bytes32 validationID = _registerDefaultValidator(); + address rewardRecipient = address(42); + bytes32 delegationID = _registerDefaultDelegatorWithRecipient(validationID, rewardRecipient); + address newRewardRecipient = address(0); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + vm.prank(DEFAULT_DELEGATOR_ADDRESS); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidRewardRecipient.selector, newRewardRecipient + ) + ); + + stakingManager.changeDelegatorRewardRecipient(delegationID, newRewardRecipient); + } + + function testChangeDelegatorRewardRecipientByNonDelegator() public { + bytes32 validationID = _registerDefaultValidator(); + address rewardRecipient = address(42); + bytes32 delegationID = _registerDefaultDelegatorWithRecipient(validationID, rewardRecipient); + address badActor = address(43); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + vm.prank(badActor); + + vm.expectRevert(abi.encodeWithSelector(StakingManager.UnauthorizedOwner.selector, badActor)); + + stakingManager.changeDelegatorRewardRecipient(delegationID, badActor); + } + + function testChangeDelegatorRewardRecipientBackToSelf() public { + bytes32 validationID = _registerDefaultValidator(); + address rewardRecipient = address(42); + bytes32 delegationID = _registerDefaultDelegatorWithRecipient(validationID, rewardRecipient); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + vm.prank(DEFAULT_DELEGATOR_ADDRESS); + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit DelegatorRewardRecipientChanged( + delegationID, DEFAULT_DELEGATOR_ADDRESS, rewardRecipient + ); + + stakingManager.changeDelegatorRewardRecipient(delegationID, DEFAULT_DELEGATOR_ADDRESS); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + uptimeSeconds: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint256 expectedValidatorFees = + _calculateValidatorFeesFromDelegator(expectedTotalReward, DEFAULT_DELEGATION_FEE_BIPS); + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + _completeDelegatorRemovalWithChecks({ + validationID: validationID, + delegationID: delegationID, + delegator: DEFAULT_DELEGATOR_ADDRESS, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedValidatorFees: expectedValidatorFees, + expectedDelegatorReward: expectedDelegatorReward, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + } + + function testChangeDelegatorRewardRecipient() public { + bytes32 validationID = _registerDefaultValidator(); + address rewardRecipient = address(42); + bytes32 delegationID = _registerDefaultDelegatorWithRecipient(validationID, rewardRecipient); + address newRewardRecipient = address(43); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + vm.prank(DEFAULT_DELEGATOR_ADDRESS); + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit DelegatorRewardRecipientChanged(delegationID, newRewardRecipient, rewardRecipient); + stakingManager.changeDelegatorRewardRecipient(delegationID, newRewardRecipient); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + uptimeSeconds: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint256 expectedValidatorFees = + _calculateValidatorFeesFromDelegator(expectedTotalReward, DEFAULT_DELEGATION_FEE_BIPS); + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + _completeDelegatorRemovalWithChecks({ + validationID: validationID, + delegationID: delegationID, + delegator: DEFAULT_DELEGATOR_ADDRESS, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedValidatorFees: expectedValidatorFees, + expectedDelegatorReward: expectedDelegatorReward, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + } + + // Delegator registration is not allowed when Validator is pending removed. + function testInitiateDelegatorRegistrationValidatorPendingRemoved() public { + bytes32 validationID = _registerDefaultValidator(); + + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + _beforeSend(_weightToValue(DEFAULT_DELEGATOR_WEIGHT), DEFAULT_DELEGATOR_ADDRESS); + + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.PendingRemoved + ) + ); + _initiateDelegatorRegistration( + validationID, + DEFAULT_DELEGATOR_ADDRESS, + DEFAULT_DELEGATOR_WEIGHT, + DEFAULT_DELEGATOR_ADDRESS + ); + } + + // Complete delegator registration may be called when validator is pending removed. + function testCompleteRegisterDelegatorValidatorPendingRemoved() public { + bytes32 validationID = _registerDefaultValidator(); + + bytes32 delegationID = _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 2, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + _setUpCompleteDelegatorRegistrationWithChecks( + validationID, + delegationID, + DEFAULT_COMPLETION_TIMESTAMP + 1, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 1 + ); + } + + // Delegator cannot initiate end delegation when validator is pending removed. + function testInitiateDelegatorRemovalValidatorPendingRemoved() public { + bytes32 validationID = _registerDefaultValidator(); + + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + _beforeSend(_weightToValue(DEFAULT_DELEGATOR_WEIGHT), DEFAULT_DELEGATOR_ADDRESS); + + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.PendingRemoved + ) + ); + _initiateDelegatorRegistration( + validationID, + DEFAULT_DELEGATOR_ADDRESS, + DEFAULT_DELEGATOR_WEIGHT, + DEFAULT_DELEGATOR_ADDRESS + ); + } + + // Delegator may complete end delegation while validator is pending removed. + function testCompleteDelegatorRemovalValidatorPendingRemoved() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + uint64 validationEndTime = DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP + 1; + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 3, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, validationEndTime - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: validationEndTime, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + uptimeSeconds: validationEndTime - DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint256 expectedValidatorFees = + _calculateValidatorFeesFromDelegator(expectedTotalReward, DEFAULT_DELEGATION_FEE_BIPS); + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + address delegator = DEFAULT_DELEGATOR_ADDRESS; + + _completeDelegatorRemovalWithChecks({ + validationID: validationID, + delegationID: delegationID, + delegator: delegator, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedValidatorFees: expectedValidatorFees, + expectedDelegatorReward: expectedDelegatorReward, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: 0, + expectedNonce: 2 + }); + } + + function testInitiateDelegatorRegistrationValidatorCompleted() public { + bytes32 validationID = _registerDefaultValidator(); + _endDefaultValidatorWithChecks(validationID, 1); + + _beforeSend(_weightToValue(DEFAULT_DELEGATOR_WEIGHT), DEFAULT_DELEGATOR_ADDRESS); + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP + 1); + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.Completed + ) + ); + _initiateDelegatorRegistration( + validationID, + DEFAULT_DELEGATOR_ADDRESS, + DEFAULT_DELEGATOR_WEIGHT, + DEFAULT_DELEGATOR_ADDRESS + ); + } + + function testCompleteDelegatorRegistrationValidatorCompleted() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _initiateDefaultDelegatorRegistration(validationID); + + _endDefaultValidatorWithChecks(validationID, 2); + + // completeDelegatorRegistration should fall through to _completeDelegatorRemoval and refund the stake + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit CompletedDelegatorRemoval(delegationID, validationID, 0, 0); + + uint256 balanceBefore = _getStakeAssetBalance(DEFAULT_DELEGATOR_ADDRESS); + + _expectStakeUnlock(DEFAULT_DELEGATOR_ADDRESS, _weightToValue(DEFAULT_DELEGATOR_WEIGHT)); + + // warp to right after validator ended + vm.warp(DEFAULT_COMPLETION_TIMESTAMP + 1); + stakingManager.completeDelegatorRegistration(delegationID, 0); + + assertEq( + _getStakeAssetBalance(DEFAULT_DELEGATOR_ADDRESS), + balanceBefore + _weightToValue(DEFAULT_DELEGATOR_WEIGHT) + ); + } + + function testInitiateDelegatorRemovalValidatorCompleted() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _endDefaultValidatorWithChecks(validationID, 2); + + uint64 delegationEndTime = DEFAULT_COMPLETION_TIMESTAMP + 1; + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint256 expectedValidatorFees = (expectedTotalReward * DEFAULT_DELEGATION_FEE_BIPS) / 10000; + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + // completeDelegatorRegistration should fall through to _completeDelegatorRemoval and refund the stake + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit CompletedDelegatorRemoval( + delegationID, validationID, expectedDelegatorReward, expectedValidatorFees + ); + + uint256 balanceBefore = _getStakeAssetBalance(DEFAULT_DELEGATOR_ADDRESS); + + _expectStakeUnlock(DEFAULT_DELEGATOR_ADDRESS, _weightToValue(DEFAULT_DELEGATOR_WEIGHT)); + _expectRewardIssuance(DEFAULT_DELEGATOR_ADDRESS, expectedDelegatorReward); + + // warp to right after validator ended + vm.warp(delegationEndTime); + vm.prank(DEFAULT_DELEGATOR_ADDRESS); + stakingManager.initiateDelegatorRemoval(delegationID, false, 0); + + assertEq( + _getStakeAssetBalance(DEFAULT_DELEGATOR_ADDRESS), + balanceBefore + _weightToValue(DEFAULT_DELEGATOR_WEIGHT) + expectedDelegatorReward + ); + } + + function testCompleteDelegatorRemovalValidatorCompleted() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + _endDefaultValidatorWithChecks(validationID, 3); + + uint256 expectedTotalReward = _defaultDelegatorExpectedTotalReward(); + + uint256 expectedValidatorFees = (expectedTotalReward * DEFAULT_DELEGATION_FEE_BIPS) / 10000; + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit CompletedDelegatorRemoval( + delegationID, validationID, expectedDelegatorReward, expectedValidatorFees + ); + uint256 balanceBefore = _getStakeAssetBalance(DEFAULT_DELEGATOR_ADDRESS); + + _expectStakeUnlock(DEFAULT_DELEGATOR_ADDRESS, _weightToValue(DEFAULT_DELEGATOR_WEIGHT)); + _expectRewardIssuance(DEFAULT_DELEGATOR_ADDRESS, expectedDelegatorReward); + + stakingManager.completeDelegatorRemoval(delegationID, 0); + + assertEq( + _getStakeAssetBalance(DEFAULT_DELEGATOR_ADDRESS), + balanceBefore + _weightToValue(DEFAULT_DELEGATOR_WEIGHT) + expectedDelegatorReward + ); + } + + function testCompleteDelegatorRemovalWrongNonce() public { + bytes32 validationID = _registerDefaultValidator(); + // Register two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + bytes32 delegationID1 = _registerDelegator({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + initRegistrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + + address delegator2 = address(0x5678567856785678567856785678567856785678); + bytes32 delegationID2 = _registerDelegator({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + initRegistrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT * 2 + DEFAULT_WEIGHT, + expectedNonce: 2, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + + // Initialize end delegation for both delegators + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: delegator1, + delegationID: delegationID1, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 3, + includeUptime: true, + force: false + }); + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: delegator2, + delegationID: delegationID2, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 4, + includeUptime: true, + force: false + }); + + // Complete ending delegator2 with delegator1's nonce + // Note that ending delegator1 with delegator2's nonce is valid + uint64 nonce = 3; + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, nonce, DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT + ); + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + vm.expectRevert(abi.encodeWithSelector(IValidatorManager.InvalidNonce.selector, nonce)); + stakingManager.completeDelegatorRemoval(delegationID2, 0); + } + + function testCompleteDelegatorRemovalImplicitNonce() public { + bytes32 validationID = _registerDefaultValidator(); + + // Register two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + bytes32 delegationID1 = _registerDelegator({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + initRegistrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + + address delegator2 = address(0x5678567856785678567856785678567856785678); + bytes32 delegationID2 = _registerDelegator({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + initRegistrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT * 2 + DEFAULT_WEIGHT, + expectedNonce: 2, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + + // Initialize end delegation for both delegators + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: delegator1, + delegationID: delegationID1, + startDelegationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 3, + includeUptime: true, + force: false + }); + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: delegator2, + delegationID: delegationID2, + startDelegationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 4, + includeUptime: true, + force: false + }); + + uint256 expectedTotalReward = _defaultDelegatorExpectedTotalReward(); + + uint256 expectedValidatorFees = + _calculateValidatorFeesFromDelegator(expectedTotalReward, DEFAULT_DELEGATION_FEE_BIPS); + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + address delegator = DEFAULT_DELEGATOR_ADDRESS; + + // Complete delegation1 by delivering the weight update from nonce 4 (delegator2's nonce) + _completeDelegatorRemovalWithChecks({ + validationID: validationID, + delegationID: delegationID1, + delegator: delegator, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedValidatorFees: expectedValidatorFees, + expectedDelegatorReward: expectedDelegatorReward, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 4 + }); + } + + function testCompleteValidatorRemoval() public virtual override { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + address validatorOwner = address(this); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT, + rewardRecipient: validatorOwner + }); + } + + function testReplayValidatorRegistration() public virtual override { + uint64 initialTimestamp = uint64(block.timestamp); + bytes32 validationID = _registerDefaultValidator(); + + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + address validatorOwner = address(this); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT, + rewardRecipient: validatorOwner + }); + + // Set the timestamp to be the same as when we registered the initial validator so that the + // expiries will be the same, leading to the same validation ID. + vm.warp(initialTimestamp); + _beforeSend(_weightToValue(DEFAULT_WEIGHT), address(this)); + + vm.expectRevert( + abi.encodeWithSelector(IValidatorManager.InvalidValidatorStatus.selector, 4) + ); + + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testCompleteValidatorRemovalWithNonValidatorRewardRecipient() public virtual { + address rewardRecipient = address(42); + bytes32 validationID = _registerDefaultValidatorWithRecipient(rewardRecipient); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + address validatorOwner = address(this); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT, + rewardRecipient: rewardRecipient + }); + } + + function testChangeValidatorRewardRecipient() public virtual { + address rewardRecipient = address(42); + bytes32 validationID = _registerDefaultValidatorWithRecipient(rewardRecipient); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + address newRecipient = address(43); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit ValidatorRewardRecipientChanged(validationID, newRecipient, rewardRecipient); + stakingManager.changeValidatorRewardRecipient(validationID, newRecipient); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: address(this), + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT, + rewardRecipient: newRecipient + }); + } + + function testChangeValidatorRewardRecipientBackToSelf() public { + address rewardRecipient = address(42); + bytes32 validationID = _registerDefaultValidatorWithRecipient(rewardRecipient); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + address newRecipient = address(this); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit ValidatorRewardRecipientChanged(validationID, newRecipient, rewardRecipient); + stakingManager.changeValidatorRewardRecipient(validationID, newRecipient); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + address validatorOwner = address(this); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT, + rewardRecipient: validatorOwner + }); + } + + function testChangeValidatorRewardRecipientWithNullAddress() public virtual { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + address newRecipient = address(0); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + vm.expectRevert( + abi.encodeWithSelector(StakingManager.InvalidRewardRecipient.selector, newRecipient) + ); + + stakingManager.changeValidatorRewardRecipient(validationID, newRecipient); + } + + function testChangeValidatorRewardRecipientByNonValidator() public { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + address badActor = address(43); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + vm.prank(badActor); + + vm.expectRevert(abi.encodeWithSelector(StakingManager.UnauthorizedOwner.selector, badActor)); + + stakingManager.changeValidatorRewardRecipient(validationID, badActor); + } + + function testInitiateValidatorRemoval() public virtual override { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + } + + function testInitiateValidatorRemovalUseStoredUptime() public { + bytes32 validationID = _registerDefaultValidator(); + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + + // Submit an uptime proof via submitUptime + uint64 uptimePercentage1 = 80; + uint64 uptime1 = ( + (DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP) * uptimePercentage1 + ) / 100; + bytes memory uptimeMsg1 = + ValidatorMessages.packValidationUptimeMessage(validationID, uptime1); + _mockGetUptimeWarpMessage(uptimeMsg1, true); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit UptimeUpdated(validationID, uptime1); + stakingManager.submitUptimeProof(validationID, 0); + + // Submit a second uptime proof via initiateValidatorRemoval. This one is not sufficient for rewards + // Submit an uptime proof via submitUptime + uint64 uptimePercentage2 = 79; + uint64 uptime2 = ( + (DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP) * uptimePercentage2 + ) / 100; + bytes memory uptimeMsg2 = + ValidatorMessages.packValidationUptimeMessage(validationID, uptime2); + _mockGetUptimeWarpMessage(uptimeMsg2, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit InitiatedValidatorRemoval( + validationID, bytes32(0), DEFAULT_WEIGHT, DEFAULT_COMPLETION_TIMESTAMP + ); + + _initiateValidatorRemoval(validationID, true); + } + + function testInitiateValidatorRemovalWithoutNewUptime() public { + bytes32 validationID = _registerDefaultValidator(); + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + + // Submit an uptime proof via submitUptime + uint64 uptimePercentage1 = 80; + uint64 uptime1 = ( + (DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP) * uptimePercentage1 + ) / 100; + bytes memory uptimeMsg1 = + ValidatorMessages.packValidationUptimeMessage(validationID, uptime1); + _mockGetUptimeWarpMessage(uptimeMsg1, true); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit UptimeUpdated(validationID, uptime1); + stakingManager.submitUptimeProof(validationID, 0); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit InitiatedValidatorRemoval( + validationID, bytes32(0), DEFAULT_WEIGHT, DEFAULT_COMPLETION_TIMESTAMP + ); + + _initiateValidatorRemoval(validationID, false); + } + + function testInitiateValidatorRemovalInsufficientUptime() public { + bytes32 validationID = _registerDefaultValidator(); + uint64 uptimePercentage = 79; + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + + bytes memory uptimeMsg = ValidatorMessages.packValidationUptimeMessage( + validationID, + ((DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP) * uptimePercentage) + / 100 + ); + _mockGetUptimeWarpMessage(uptimeMsg, true); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.ValidatorIneligibleForRewards.selector, validationID + ) + ); + + _initiateValidatorRemoval(validationID, true); + } + + function testSubmitUptimeProofPoaValidator() public { + bytes32 defaultInitialValidationID = sha256(abi.encodePacked(DEFAULT_SUBNET_ID, uint32(1))); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.ValidatorNotPoS.selector, defaultInitialValidationID + ) + ); + stakingManager.submitUptimeProof(defaultInitialValidationID, 0); + } + + function testSubmitUptimeProofInactiveValidator() public { + bytes32 validationID = _registerDefaultValidator(); + + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + _beforeSend(_weightToValue(DEFAULT_DELEGATOR_WEIGHT), DEFAULT_DELEGATOR_ADDRESS); + + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.PendingRemoved + ) + ); + stakingManager.submitUptimeProof(validationID, 0); + } + + function testEndValidationPoAValidator() public { + bytes32 validationID = sha256(abi.encodePacked(DEFAULT_SUBNET_ID, uint32(1))); + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit InitiatedValidatorRemoval( + validationID, bytes32(0), DEFAULT_WEIGHT, DEFAULT_COMPLETION_TIMESTAMP + ); + + _initiateValidatorRemoval(validationID, false); + + uint256 balanceBefore = _getStakeAssetBalance(address(this)); + + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, false); + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + + stakingManager.completeValidatorRemoval(0); + + assertEq(_getStakeAssetBalance(address(this)), balanceBefore); + } + + function testDelegationToPoAValidator() public { + bytes32 defaultInitialValidationID = sha256(abi.encodePacked(DEFAULT_SUBNET_ID, uint32(1))); + + _beforeSend(_weightToValue(DEFAULT_DELEGATOR_WEIGHT), DEFAULT_DELEGATOR_ADDRESS); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.ValidatorNotPoS.selector, defaultInitialValidationID + ) + ); + + _initiateDelegatorRegistration( + defaultInitialValidationID, + DEFAULT_DELEGATOR_ADDRESS, + DEFAULT_DELEGATOR_WEIGHT, + address(0) + ); + } + + function testDelegationOverWeightLimit() public { + bytes32 validationID = _registerDefaultValidator(); + + uint64 delegatorWeight = DEFAULT_WEIGHT * DEFAULT_MAXIMUM_STAKE_MULTIPLIER + 1; + + _beforeSend(_weightToValue(delegatorWeight), DEFAULT_DELEGATOR_ADDRESS); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.MaxWeightExceeded.selector, delegatorWeight + DEFAULT_WEIGHT + ) + ); + + _initiateDelegatorRegistration( + validationID, DEFAULT_DELEGATOR_ADDRESS, delegatorWeight, DEFAULT_DELEGATOR_ADDRESS + ); + } + + function testCompleteDelegatorRegistrationAlreadyRegistered() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidDelegatorStatus.selector, DelegatorStatus.Active + ) + ); + + stakingManager.completeDelegatorRegistration(delegationID, 0); + } + + function testCompleteDelegatorRegistrationWrongValidationID() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _initiateDefaultDelegatorRegistration(validationID); + + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + delegationID, 1, DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT + ); + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + // The invalid validationID has sent no weight updates, so its nonce should be 0 + vm.expectRevert(abi.encodeWithSelector(IValidatorManager.InvalidNonce.selector, 1)); + + vm.warp(DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP); + stakingManager.completeDelegatorRegistration(delegationID, 0); + } + + function testCompleteDelegatorRemovalWrongValidationID() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(delegationID, 2, DEFAULT_WEIGHT); + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + vm.expectRevert(abi.encodeWithSelector(IValidatorManager.InvalidNonce.selector, 2)); + + stakingManager.completeDelegatorRemoval(delegationID, 0); + } + + function testInitiateDelegatorRemovalNotRegistered() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _initiateDefaultDelegatorRegistration(validationID); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidDelegatorStatus.selector, DelegatorStatus.PendingAdded + ) + ); + + stakingManager.initiateDelegatorRemoval(delegationID, true, 0); + } + + function testInitiateDelegatorRemovalWrongSender() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + vm.expectRevert( + abi.encodeWithSelector(StakingManager.UnauthorizedOwner.selector, address(123)) + ); + + vm.prank(address(123)); + stakingManager.initiateDelegatorRemoval(delegationID, true, 0); + } + + function testCompleteDelegatorRegistrationForCompletedDelegatorRegistrationWhileValidatorPendingRemoved( + ) public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _initiateDefaultDelegatorRegistration(validationID); + + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 2, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + _setUpCompleteDelegatorRegistrationWithChecks( + validationID, delegationID, DEFAULT_COMPLETION_TIMESTAMP + 1, 0, 2 + ); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: address(this), + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT, + rewardRecipient: address(this) + }); + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP + 1 + DEFAULT_MINIMUM_STAKE_DURATION); + _expectStakeUnlock(DEFAULT_DELEGATOR_ADDRESS, _weightToValue(DEFAULT_DELEGATOR_WEIGHT)); + stakingManager.initiateDelegatorRemoval(delegationID, true, 0); + } + + function testCompleteDelegatorRemovalWhileActive() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidDelegatorStatus.selector, DelegatorStatus.Active + ) + ); + + stakingManager.completeDelegatorRemoval(delegationID, 0); + } + + function testCompleteDelegatorRegistrationValidatorPendingRemoved() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _initiateDefaultDelegatorRegistration(validationID); + + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 2, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + _setUpCompleteDelegatorRegistrationWithChecks( + validationID, delegationID, DEFAULT_COMPLETION_TIMESTAMP + 1, 0, 2 + ); + + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.PendingRemoved + ) + ); + + stakingManager.initiateDelegatorRemoval(delegationID, false, 0); + } + + function testResendEndDelegationWhileActive() public { + bytes32 validationID = _registerDefaultValidator(); + bytes32 delegationID = _registerDefaultDelegator(validationID); + + vm.expectRevert( + abi.encodeWithSelector( + StakingManager.InvalidDelegatorStatus.selector, DelegatorStatus.Active + ) + ); + + stakingManager.resendUpdateDelegator(delegationID); + } + + function testForceInitiateValidatorRemoval() public { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: true + }); + } + + function testForceInitiateValidatorRemovalInsufficientUptime() public { + bytes32 validationID = _registerDefaultValidator(); + uint64 uptimePercentage = 79; + + vm.warp(DEFAULT_COMPLETION_TIMESTAMP); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + + bytes memory uptimeMsg = ValidatorMessages.packValidationUptimeMessage( + validationID, + ((DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP) * uptimePercentage) + / 100 + ); + _mockGetUptimeWarpMessage(uptimeMsg, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit InitiatedValidatorRemoval( + validationID, bytes32(0), DEFAULT_WEIGHT, DEFAULT_COMPLETION_TIMESTAMP + ); + + _forceInitiateValidatorRemoval(validationID, true); + } + + function testValueToWeightTruncated() public { + // default weightToValueFactor is 1e12 + vm.expectRevert(abi.encodeWithSelector(StakingManager.InvalidStakeAmount.selector, 1e11)); + stakingManager.valueToWeight(1e11); + } + + function testValueToWeightExceedsUInt64Max() public { + // default weightToValueFactor is 1e12 + vm.expectRevert(abi.encodeWithSelector(StakingManager.InvalidStakeAmount.selector, 1e40)); + stakingManager.valueToWeight(1e40); + } + + function testValueToWeight() public view { + uint64 w1 = stakingManager.valueToWeight(1e12); + uint64 w2 = stakingManager.valueToWeight(1e18); + uint64 w3 = stakingManager.valueToWeight(1e27); + + assertEq(w1, 1); + assertEq(w2, 1e6); + assertEq(w3, 1e15); + } + + function testWeightToValue() public view { + uint256 v1 = stakingManager.weightToValue(1); + uint256 v2 = stakingManager.weightToValue(1e6); + uint256 v3 = stakingManager.weightToValue(1e15); + + assertEq(v1, 1e12); + assertEq(v2, 1e18); + assertEq(v3, 1e27); + } + + function testStakingManagerStorageSlot() public view { + assertEq( + _erc7201StorageSlot("StakingManager"), stakingManager.STAKING_MANAGER_STORAGE_LOCATION() + ); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount, + address rewardRecipient + ) internal virtual returns (bytes32); + + function _completeValidatorRegistration( + uint32 messageIndex + ) internal virtual override returns (bytes32) { + return stakingManager.completeValidatorRegistration(messageIndex); + } + + function _initiateValidatorRemoval( + bytes32 validationID, + bool includeUptime + ) internal virtual override { + stakingManager.initiateValidatorRemoval(validationID, includeUptime, 0); + } + + function _forceInitiateValidatorRemoval( + bytes32 validationID, + bool includeUptime + ) internal virtual override { + stakingManager.forceInitiateValidatorRemoval(validationID, includeUptime, 0); + } + + function _completeValidatorRemoval( + uint32 messageIndex + ) internal virtual override returns (bytes32) { + return stakingManager.completeValidatorRemoval(messageIndex); + } + + function _initiateDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight, + address rewardRecipient + ) internal virtual returns (bytes32); + + // + // Staking specific setup utilities + // + function _beforeRegisterValidator( + bytes32 validationID, + address rewardRecipient + ) internal virtual override { + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit InitiatedStakingValidatorRegistration( + validationID, + address(this), + DEFAULT_DELEGATION_FEE_BIPS, + DEFAULT_MINIMUM_STAKE_DURATION, + rewardRecipient + ); + } + + function _setUpInitiateDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight, + uint64 registrationTimestamp, + uint64 expectedValidatorWeight, + uint64 expectedNonce, + address rewardRecipient + ) internal returns (bytes32) { + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, expectedNonce, expectedValidatorWeight + ); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + vm.warp(registrationTimestamp); + + _beforeSend(_weightToValue(weight), delegatorAddress); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit InitiatedValidatorWeightUpdate( + validationID, expectedNonce, bytes32(0), expectedValidatorWeight + ); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit InitiatedDelegatorRegistration({ + delegationID: keccak256(abi.encodePacked(validationID, expectedNonce)), + validationID: validationID, + delegatorAddress: delegatorAddress, + nonce: expectedNonce, + validatorWeight: expectedValidatorWeight, + delegatorWeight: weight, + setWeightMessageID: bytes32(0), + rewardRecipient: rewardRecipient + }); + + return + _initiateDelegatorRegistration(validationID, delegatorAddress, weight, rewardRecipient); + } + + function _setUpCompleteDelegatorRegistration( + bytes32 delegationID, + uint64 completeRegistrationTimestamp, + bytes memory setValidatorWeightPayload + ) internal { + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + vm.warp(completeRegistrationTimestamp); + stakingManager.completeDelegatorRegistration(delegationID, 0); + } + + function _setUpCompleteDelegatorRegistrationWithChecks( + bytes32 validationID, + bytes32 delegationID, + uint64 completeRegistrationTimestamp, + uint64 expectedValidatorWeight, + uint64 expectedNonce + ) internal { + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, expectedNonce, expectedValidatorWeight + ); + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorWeightUpdate(validationID, expectedNonce, expectedValidatorWeight); + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit CompletedDelegatorRegistration({ + delegationID: delegationID, + validationID: validationID, + startTime: completeRegistrationTimestamp + }); + _setUpCompleteDelegatorRegistration( + delegationID, completeRegistrationTimestamp, setValidatorWeightPayload + ); + } + + function _registerDefaultDelegator( + bytes32 validationID + ) internal returns (bytes32 delegationID) { + return _registerDelegator({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + initRegistrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + } + + function _registerDefaultDelegatorWithRecipient( + bytes32 validationID, + address rewardRecipient + ) internal returns (bytes32 delegationID) { + return _registerDelegator({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + initRegistrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: rewardRecipient + }); + } + + function _initiateDefaultDelegatorRegistration( + bytes32 validationID + ) internal returns (bytes32) { + return _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1, + rewardRecipient: DEFAULT_DELEGATOR_ADDRESS + }); + } + + function _completeDefaultDelegatorRegistration( + bytes32 validationID, + bytes32 delegationID + ) internal { + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, 1, DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT + ); + _setUpCompleteDelegatorRegistration({ + delegationID: delegationID, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + setValidatorWeightPayload: setValidatorWeightPayload + }); + } + + function _completeDefaultDelegator(bytes32 validationID, bytes32 delegationID) internal { + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + uint256 expectedTotalReward = _defaultDelegatorExpectedTotalReward(); + uint256 expectedValidatorFees = + _calculateValidatorFeesFromDelegator(expectedTotalReward, DEFAULT_DELEGATION_FEE_BIPS); + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + _completeDelegatorRemovalWithChecks({ + validationID: validationID, + delegationID: delegationID, + delegator: DEFAULT_DELEGATOR_ADDRESS, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedValidatorFees: expectedValidatorFees, + expectedDelegatorReward: expectedDelegatorReward, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + } + + function _registerDelegator( + bytes32 validationID, + address delegatorAddress, + uint64 weight, + uint64 initRegistrationTimestamp, + uint64 completeRegistrationTimestamp, + uint64 expectedValidatorWeight, + uint64 expectedNonce, + address rewardRecipient + ) internal returns (bytes32) { + bytes32 delegationID = _setUpInitiateDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegatorAddress, + weight: weight, + registrationTimestamp: initRegistrationTimestamp, + expectedValidatorWeight: expectedValidatorWeight, + expectedNonce: expectedNonce, + rewardRecipient: rewardRecipient + }); + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, expectedNonce, expectedValidatorWeight + ); + + _setUpCompleteDelegatorRegistration( + delegationID, completeRegistrationTimestamp, setValidatorWeightPayload + ); + return delegationID; + } + + function _initiateDelegatorRemovalValidatorActiveWithChecks( + bytes32 validationID, + address sender, + bytes32 delegationID, + uint64 startDelegationTimestamp, + uint64 endDelegationTimestamp, + uint64 expectedValidatorWeight, + uint64 expectedNonce, + bool includeUptime, + bool force + ) internal { + bytes memory setValidatorWeightPayload = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, expectedNonce, expectedValidatorWeight + ); + bytes memory uptimeMsg = ValidatorMessages.packValidationUptimeMessage( + validationID, endDelegationTimestamp - startDelegationTimestamp + ); + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit InitiatedValidatorWeightUpdate({ + validationID: validationID, + nonce: expectedNonce, + weight: expectedValidatorWeight, + weightUpdateMessageID: bytes32(0) + }); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit InitiatedDelegatorRemoval({delegationID: delegationID, validationID: validationID}); + + _initiateDelegatorRemovalValidatorActive({ + sender: sender, + delegationID: delegationID, + endDelegationTimestamp: endDelegationTimestamp, + includeUptime: includeUptime, + force: force, + setValidatorWeightPayload: setValidatorWeightPayload, + uptimePayload: uptimeMsg + }); + } + + function _initiateDelegatorRemovalValidatorActive( + address sender, + bytes32 delegationID, + uint64 endDelegationTimestamp, + bool includeUptime, + bool force, + bytes memory setValidatorWeightPayload, + bytes memory uptimePayload + ) internal { + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + + if (includeUptime) { + _mockGetUptimeWarpMessage(uptimePayload, true); + } + _initiateDelegatorRemoval({ + sender: sender, + delegationID: delegationID, + endDelegationTimestamp: endDelegationTimestamp, + includeUptime: includeUptime, + force: force + }); + } + + function _initiateDelegatorRemoval( + address sender, + bytes32 delegationID, + uint64 endDelegationTimestamp, + bool includeUptime, + bool force + ) internal { + vm.warp(endDelegationTimestamp); + vm.prank(sender); + if (force) { + stakingManager.forceInitiateDelegatorRemoval(delegationID, includeUptime, 0); + } else { + stakingManager.initiateDelegatorRemoval(delegationID, includeUptime, 0); + } + } + + function _endDefaultValidatorWithChecks(bytes32 validationID, uint64 expectedNonce) internal { + _endValidationWithChecks({ + validationID: validationID, + validatorOwner: address(this), + completeRegistrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + validatorWeight: DEFAULT_WEIGHT, + expectedNonce: expectedNonce, + rewardRecipient: address(this) + }); + } + + function _endDefaultValidator(bytes32 validationID, uint64 expectedNonce) internal { + address validatorOwner = address(this); + _endValidationWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + completeRegistrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + validatorWeight: DEFAULT_WEIGHT, + expectedNonce: expectedNonce, + rewardRecipient: validatorOwner + }); + } + + function _endValidationWithChecks( + bytes32 validationID, + address validatorOwner, + uint64 completeRegistrationTimestamp, + uint64 completionTimestamp, + uint64 validatorWeight, + uint64 expectedNonce, + address rewardRecipient + ) internal { + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, expectedNonce, 0); + bytes memory uptimeMessage = ValidatorMessages.packValidationUptimeMessage( + validationID, completionTimestamp - completeRegistrationTimestamp + ); + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: completionTimestamp, + setWeightMessage: setWeightMessage, + includeUptime: true, + uptimeMessage: uptimeMessage, + force: false + }); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(validatorWeight), + validatorStartTime: completeRegistrationTimestamp, + stakingStartTime: completeRegistrationTimestamp, + stakingEndTime: completionTimestamp, + uptimeSeconds: completionTimestamp - completeRegistrationTimestamp + }); + + _completeValidatorRemovalWithChecks({ + validationID: validationID, + validatorOwner: validatorOwner, + expectedReward: expectedReward, + validatorWeight: validatorWeight, + rewardRecipient: rewardRecipient + }); + } + + function _completeValidatorRemovalWithChecks( + bytes32 validationID, + address validatorOwner, + uint256 expectedReward, + uint64 validatorWeight, + address rewardRecipient + ) internal { + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, false); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorRemoval(validationID); + uint256 balanceBefore = _getStakeAssetBalance(validatorOwner); + uint256 rewardRecipientBalanceBefore = _getStakeAssetBalance(rewardRecipient); + + _expectStakeUnlock(validatorOwner, _weightToValue(validatorWeight)); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit ValidatorRewardClaimed(validationID, rewardRecipient, expectedReward); + _expectRewardIssuance(rewardRecipient, expectedReward); + + _completeValidatorRemoval(l1ValidatorRegistrationMessage); + + if (rewardRecipient == validatorOwner) { + assertEq( + _getStakeAssetBalance(validatorOwner), + balanceBefore + _weightToValue(validatorWeight) + expectedReward + ); + } else { + assertEq( + _getStakeAssetBalance(validatorOwner), + balanceBefore + _weightToValue(validatorWeight) + ); + + assertEq( + _getStakeAssetBalance(rewardRecipient), + rewardRecipientBalanceBefore + expectedReward + ); + } + } + + function _completeValidatorRemoval( + bytes memory l1ValidatorRegistrationMessage + ) internal { + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + stakingManager.completeValidatorRemoval(0); + } + + function _completeDelegatorRemovalWithChecks( + bytes32 validationID, + bytes32 delegationID, + address delegator, + uint64 delegatorWeight, + uint256 expectedValidatorFees, + uint256 expectedDelegatorReward, + uint64 validatorWeight, + uint64 expectedValidatorWeight, + uint64 expectedNonce + ) internal { + (address rewardRecipient,) = stakingManager.getDelegatorRewardInfo(delegationID); + bytes memory weightUpdateMessage = ValidatorMessages.packL1ValidatorWeightMessage( + validationID, expectedNonce, validatorWeight + ); + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorWeightUpdate(validationID, expectedNonce, validatorWeight); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit DelegatorRewardClaimed(delegationID, rewardRecipient, expectedDelegatorReward); + + vm.expectEmit(true, true, true, true, address(stakingManager)); + emit CompletedDelegatorRemoval( + delegationID, validationID, expectedDelegatorReward, expectedValidatorFees + ); + uint256 balanceBefore = _getStakeAssetBalance(delegator); + uint256 rewardRecipientBalanceBefore = _getStakeAssetBalance(rewardRecipient); + + _expectStakeUnlock(delegator, _weightToValue(delegatorWeight)); + _expectRewardIssuance(rewardRecipient, expectedDelegatorReward); + + _completeDelegatorRemoval(delegationID, weightUpdateMessage); + + assertEq(validatorManager.getValidator(validationID).weight, expectedValidatorWeight); + + if (rewardRecipient == delegator) { + assertEq( + _getStakeAssetBalance(delegator), + balanceBefore + _weightToValue(delegatorWeight) + expectedDelegatorReward + ); + } else { + assertEq( + _getStakeAssetBalance(delegator), balanceBefore + _weightToValue(delegatorWeight) + ); + + assertEq( + _getStakeAssetBalance(rewardRecipient), + rewardRecipientBalanceBefore + expectedDelegatorReward + ); + } + } + + function _completeDelegatorRemoval( + bytes32 delegationID, + bytes memory weightUpdateMessage + ) internal { + _mockGetPChainWarpMessage(weightUpdateMessage, true); + stakingManager.completeDelegatorRemoval(delegationID, 0); + } + + function _initiateAndCompleteDelegatorRemovalWithChecks( + bytes32 validationID, + bytes32 delegationID + ) internal { + _initiateDelegatorRemovalValidatorActiveWithChecks({ + validationID: validationID, + sender: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2, + includeUptime: true, + force: false + }); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: 0, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + uptimeSeconds: 0 + }); + + uint256 expectedValidatorFees = + _calculateValidatorFeesFromDelegator(expectedTotalReward, DEFAULT_DELEGATION_FEE_BIPS); + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + address delegator = DEFAULT_DELEGATOR_ADDRESS; + + _completeDelegatorRemovalWithChecks({ + validationID: validationID, + delegationID: delegationID, + delegator: delegator, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedValidatorFees: expectedValidatorFees, + expectedDelegatorReward: expectedDelegatorReward, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + } + + function _getStakeAssetBalance( + address account + ) internal virtual returns (uint256); + function _expectStakeUnlock(address account, uint256 amount) internal virtual; + function _expectRewardIssuance(address account, uint256 amount) internal virtual; + + function _defaultDelegatorExpectedTotalReward() internal view returns (uint256) { + return rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + uptimeSeconds: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP + }); + } + + function _defaultPoSSettings() internal pure returns (StakingManagerSettings memory) { + return StakingManagerSettings({ + manager: ValidatorManager(address(0)), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + weightToValueFactor: DEFAULT_WEIGHT_TO_VALUE_FACTOR, + rewardCalculator: IRewardCalculator(address(0)), + uptimeBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID + }); + } + + function _calculateValidatorFeesFromDelegator( + uint256 totalReward, + uint64 delegationFeeBips + ) internal pure returns (uint256) { + return (totalReward * delegationFeeBips) / 10000; + } +} diff --git a/icm-contracts/contracts/validator-manager/tests/ValidatorManagerTests.t.sol b/icm-contracts/contracts/validator-manager/tests/ValidatorManagerTests.t.sol new file mode 100644 index 000000000..1db20c9d9 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/ValidatorManagerTests.t.sol @@ -0,0 +1,939 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import { + IValidatorManager, ValidatorManager, ValidatorManagerSettings +} from "../ValidatorManager.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; +import {WarpMessage, IWarpMessenger} from "@subnet-evm/IWarpMessenger.sol"; +import { + IACP99Manager, + ConversionData, + InitialValidator, + PChainOwner, + ValidatorStatus +} from "../interfaces/IACP99Manager.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; + +// TODO: Remove this once all unit tests implemented +// solhint-disable no-empty-blocks +abstract contract ValidatorManagerTest is Test { + bytes32 public constant DEFAULT_SUBNET_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes public constant DEFAULT_NODE_ID = bytes(hex"1234123412341234123412341234123412341234"); + bytes public constant DEFAULT_INITIAL_VALIDATOR_NODE_ID_1 = + bytes(hex"2341234123412341234123412341234123412341"); + bytes public constant DEFAULT_INITIAL_VALIDATOR_NODE_ID_2 = + bytes(hex"3412341234123412341234123412341234123412"); + bytes public constant DEFAULT_BLS_PUBLIC_KEY = bytes( + hex"123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + ); + bytes32 public constant DEFAULT_SOURCE_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + bytes32 public constant DEFAULT_SUBNET_CONVERSION_ID = + bytes32(hex"67e8531265d8e97bd5c23534a37f4ea42d41934ddf8fe2c77c27fac9ef89f973"); + address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; + + uint64 public constant DEFAULT_WEIGHT = 1e6; + // Set the default weight to 1e10 to avoid churn issues + uint64 public constant DEFAULT_INITIAL_VALIDATOR_WEIGHT = DEFAULT_WEIGHT * 1e4; + uint64 public constant DEFAULT_INITIAL_TOTAL_WEIGHT = + DEFAULT_INITIAL_VALIDATOR_WEIGHT + DEFAULT_WEIGHT; + uint256 public constant DEFAULT_MINIMUM_STAKE_AMOUNT = 20e12; + uint256 public constant DEFAULT_MAXIMUM_STAKE_AMOUNT = 1e22; + uint64 public constant DEFAULT_CHURN_PERIOD = 1 hours; + uint8 public constant DEFAULT_MAXIMUM_CHURN_PERCENTAGE = 20; + uint8 public constant DEFAULT_MAXIMUM_HOURLY_CHURN = 0; + uint64 public constant DEFAULT_REGISTRATION_TIMESTAMP = 1000; + uint256 public constant DEFAULT_STARTING_TOTAL_WEIGHT = 1e10 + DEFAULT_WEIGHT; + uint64 public constant DEFAULT_MINIMUM_VALIDATION_DURATION = 24 hours; + uint64 public constant DEFAULT_COMPLETION_TIMESTAMP = 100_000; + uint64 public constant REGISTRATION_EXPIRY_LENGTH = 1 days; + // solhint-disable-next-line var-name-mixedcase + PChainOwner public DEFAULT_P_CHAIN_OWNER; + + ValidatorManager public validatorManager; + + // Used to create unique validator IDs in {_newNodeID} + uint64 public nodeIDCounter = 0; + + event RegisteredInitialValidator( + bytes32 indexed validationID, + bytes20 indexed nodeID, + bytes32 indexed subnetID, + uint64 weight + ); + + event InitiatedValidatorRegistration( + bytes32 indexed validationID, + bytes20 indexed nodeID, + bytes32 registrationMessageID, + uint64 registrationExpiry, + uint64 weight + ); + + event CompletedValidatorRegistration(bytes32 indexed validationID, uint64 weight); + + event InitiatedValidatorRemoval( + bytes32 indexed validationID, + bytes32 validatorWeightMessageID, + uint64 weight, + uint64 endTime + ); + + event CompletedValidatorRemoval(bytes32 indexed validationID); + + event InitiatedValidatorWeightUpdate( + bytes32 indexed validationID, uint64 nonce, bytes32 weightUpdateMessageID, uint64 weight + ); + + event CompletedValidatorWeightUpdate(bytes32 indexed validationID, uint64 nonce, uint64 weight); + + event ValidatorWeightUpdate( + bytes32 indexed validationID, + uint64 indexed nonce, + uint64 weight, + bytes32 setWeightMessageID + ); + + receive() external payable {} + fallback() external payable {} + + function setUp() public virtual { + address[] memory addresses = new address[](1); + addresses[0] = 0x1234567812345678123456781234567812345678; + DEFAULT_P_CHAIN_OWNER = PChainOwner({threshold: 1, addresses: addresses}); + } + + function testInitiateValidatorRegistrationSuccess() public { + _setUpInitiateValidatorRegistration( + DEFAULT_NODE_ID, + DEFAULT_SUBNET_ID, + DEFAULT_WEIGHT, + DEFAULT_BLS_PUBLIC_KEY, + address(this) + ); + } + + function testInitiateValidatorRegistrationExcessiveChurn() public { + // TODO: implement + } + + function testInitiateValidatorRegistrationInsufficientStake() public { + // TODO: implement + } + + function testInitiateValidatorRegistrationExcessiveStake() public { + // TODO: implement + } + + function testInitiateValidatorRegistrationInsufficientDuration() public { + // TODO: implement + } + + function testInitiateValidatorRegistrationPChainOwnerThresholdTooLarge() public { + // Threshold too large + address[] memory addresses = new address[](1); + addresses[0] = 0x1234567812345678123456781234567812345678; + PChainOwner memory invalidPChainOwner1 = PChainOwner({threshold: 2, addresses: addresses}); + _beforeSend(_weightToValue(DEFAULT_WEIGHT), address(this)); + vm.expectRevert( + abi.encodeWithSelector(IValidatorManager.InvalidPChainOwnerThreshold.selector, 2, 1) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: invalidPChainOwner1, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testInitiateValidatorRegistrationZeroPChainOwnerThreshold() public { + // Zero threshold for non-zero address + address[] memory addresses = new address[](1); + addresses[0] = 0x1234567812345678123456781234567812345678; + PChainOwner memory invalidPChainOwner1 = PChainOwner({threshold: 0, addresses: addresses}); + _beforeSend(_weightToValue(DEFAULT_WEIGHT), address(this)); + vm.expectRevert( + abi.encodeWithSelector(IValidatorManager.InvalidPChainOwnerThreshold.selector, 0, 1) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: invalidPChainOwner1, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testInitiateValidatorRegistrationPChainOwnerAddressesUnsorted() public { + // Addresses not sorted + address[] memory addresses = new address[](2); + addresses[0] = 0x1234567812345678123456781234567812345678; + addresses[1] = 0x0123456781234567812345678123456781234567; + PChainOwner memory invalidPChainOwner1 = PChainOwner({threshold: 1, addresses: addresses}); + + _beforeSend(_weightToValue(DEFAULT_WEIGHT), address(this)); + vm.expectRevert( + abi.encodeWithSelector(IValidatorManager.InvalidPChainOwnerAddresses.selector) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: invalidPChainOwner1, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testInitiateValidatorRegistrationDuplicatePChainOwnerAddress() public { + // Addresses not sorted + address[] memory addresses = new address[](2); + addresses[0] = 0x1234567812345678123456781234567812345678; + addresses[1] = 0x1234567812345678123456781234567812345678; + PChainOwner memory invalidPChainOwner1 = PChainOwner({threshold: 1, addresses: addresses}); + + _beforeSend(_weightToValue(DEFAULT_WEIGHT), address(this)); + vm.expectRevert( + abi.encodeWithSelector(IValidatorManager.InvalidPChainOwnerAddresses.selector) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: invalidPChainOwner1, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testInitiateValidatorRegistrationPChainOwnerZeroAddress() public { + // Addresses not sorted + address[] memory addresses = new address[](1); + addresses[0] = address(0); + PChainOwner memory invalidPChainOwner1 = PChainOwner({threshold: 1, addresses: addresses}); + + _beforeSend(_weightToValue(DEFAULT_WEIGHT), address(this)); + vm.expectRevert(abi.encodeWithSelector(IValidatorManager.ZeroAddress.selector)); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: invalidPChainOwner1, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + // The following tests call functions that are implemented in ValidatorManager, but access state that's + // only set in NativeTokenValidatorManager. Therefore we call them via the concrete type, rather than a + // reference to the abstract type. + function testResendRegisterValidatorMessage() public { + bytes32 validationID = _setUpInitiateValidatorRegistration( + DEFAULT_NODE_ID, + DEFAULT_SUBNET_ID, + DEFAULT_WEIGHT, + DEFAULT_BLS_PUBLIC_KEY, + address(this) + ); + (, bytes memory registerL1ValidatorMessage) = ValidatorMessages + .packRegisterL1ValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: DEFAULT_SUBNET_ID, + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationExpiry: uint64(block.timestamp) + 1 days, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }) + ); + _mockSendWarpMessage(registerL1ValidatorMessage, bytes32(0)); + validatorManager.resendRegisterValidatorMessage(validationID); + } + + function testCompleteValidatorRegistration() public { + _registerDefaultValidator(); + } + + function testInitiateValidatorRemoval() public virtual { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage; + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: false, + uptimeMessage: uptimeMessage, + force: false + }); + } + + function testResendEndValidation() public virtual { + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage; + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: false, + uptimeMessage: uptimeMessage, + force: false + }); + + bytes memory setValidatorWeightPayload = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + validatorManager.resendValidatorRemovalMessage(validationID); + } + + function testCompleteValidatorRemoval() public virtual { + _registerAndCompleteDefaultValidator(); + } + + function testReplayValidatorRegistration() public virtual { + uint64 initialTimestamp = uint64(block.timestamp); + bytes32 validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage; + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: false, + uptimeMessage: uptimeMessage, + force: false + }); + + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, false); + + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorRemoval(validationID); + + _completeValidatorRemoval(0); + + // Set the timestamp to be the same as when we registered the initial validator so that the + // expiries will be the same, leading to the same validation ID. + vm.warp(initialTimestamp); + _beforeSend(_weightToValue(DEFAULT_WEIGHT), address(this)); + + vm.expectRevert( + abi.encodeWithSelector(IValidatorManager.InvalidValidatorStatus.selector, 4) + ); + + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testCompleteInvalidatedValidation() public { + bytes32 validationID = _setUpInitiateValidatorRegistration( + DEFAULT_NODE_ID, + DEFAULT_SUBNET_ID, + DEFAULT_WEIGHT, + DEFAULT_BLS_PUBLIC_KEY, + address(this) + ); + + uint64 totalWeight = validatorManager.l1TotalWeight(); + + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, false); + + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorRemoval(validationID); + + _completeValidatorRemoval(0); + + assertEq(validatorManager.l1TotalWeight(), totalWeight - DEFAULT_WEIGHT); + } + + function testInitialWeightsTooLow() public { + vm.prank(address(0x123)); + IACP99Manager manager = _setUp(); + + _mockGetBlockchainID(); + + ConversionData memory conversionData = _defaultConversionDataWeightsTooLow(); + bytes32 id = sha256(ValidatorMessages.packConversionData(conversionData)); + + _mockGetPChainWarpMessage(ValidatorMessages.packSubnetToL1ConversionMessage(id), true); + vm.expectRevert(abi.encodeWithSelector(IValidatorManager.InvalidTotalWeight.selector, 4)); + manager.initializeValidatorSet(conversionData, 0); + } + + function testRemoveValidatorTotalWeight5() public { + // Use prank here, because otherwise each test will end up with a different contract address, leading to a different subnet conversion hash. + vm.prank(address(0x123)); + IACP99Manager manager = _setUp(); + + _mockGetBlockchainID(); + + ConversionData memory conversion = _defaultConversionDataTotalWeight5(); + bytes32 id = sha256(ValidatorMessages.packConversionData(conversion)); + _mockGetPChainWarpMessage(ValidatorMessages.packSubnetToL1ConversionMessage(id), true); + manager.initializeValidatorSet(conversion, 0); + + bytes32 validationID = sha256(abi.encodePacked(DEFAULT_SUBNET_ID, uint32(0))); + vm.expectRevert(abi.encodeWithSelector(IValidatorManager.InvalidTotalWeight.selector, 4)); + _forceInitiateValidatorRemoval(validationID, false); + } + + function testCumulativeChurnRegistration() public { + uint64 churnThreshold = + (uint64(DEFAULT_STARTING_TOTAL_WEIGHT) * DEFAULT_MAXIMUM_CHURN_PERCENTAGE) / 100; + _beforeSend(_weightToValue(churnThreshold), address(this)); + + // First registration should succeed + _registerValidator({ + nodeID: _newNodeID(), + subnetID: DEFAULT_SUBNET_ID, + weight: churnThreshold, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + rewardRecipient: address(this) + }); + + _beforeSend(DEFAULT_MINIMUM_STAKE_AMOUNT, address(this)); + + // Second call should fail + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.MaxChurnRateExceeded.selector, + churnThreshold + _valueToWeight(DEFAULT_MINIMUM_STAKE_AMOUNT) + ) + ); + _initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: _valueToWeight(DEFAULT_MINIMUM_STAKE_AMOUNT) + }); + } + + function testCumulativeChurnRegistrationAndEndValidation() public { + // Registration should succeed + bytes32 validationID = _registerValidator({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: _valueToWeight(DEFAULT_MINIMUM_STAKE_AMOUNT), + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + rewardRecipient: address(this) + }); + + uint64 churnThreshold = + (uint64(DEFAULT_STARTING_TOTAL_WEIGHT) * DEFAULT_MAXIMUM_CHURN_PERCENTAGE) / 100; + _beforeSend(_weightToValue(churnThreshold), address(this)); + + vm.warp(block.timestamp + 1 days + 1); + + // Registration should succeed + _registerValidator({ + nodeID: _newNodeID(), + subnetID: DEFAULT_SUBNET_ID, + weight: churnThreshold, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + 25 hours, + rewardRecipient: address(this) + }); + + // Second call should fail + // The first registration churn amount is not part of the new churn amount since + // a new churn period has started. + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.MaxChurnRateExceeded.selector, + _valueToWeight(DEFAULT_MINIMUM_STAKE_AMOUNT) + churnThreshold + ) + ); + + _initiateValidatorRemoval(validationID, false); + } + + function testInitiateValidatorRegistrationUnauthorizedCaller() public { + vm.prank(address(0x123)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, address(0x123) + ) + ); + validatorManager.initiateValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }); + } + + function testCompleteValidatorRegistrationUnauthorizedCaller() public { + vm.prank(address(0x123)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, address(0x123) + ) + ); + validatorManager.completeValidatorRegistration(0); + } + + function testInitiateValidatorWeightUpdateUnauthorizedCaller() public { + vm.prank(address(0x123)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, address(0x123) + ) + ); + validatorManager.initiateValidatorWeightUpdate(bytes32(0), 0); + } + + function initiateValidatorWeightUpdateInactiveValidator() public { + bytes32 validationID = _registerAndCompleteDefaultValidator(); + + vm.expectRevert( + abi.encodeWithSelector( + IValidatorManager.InvalidValidatorStatus.selector, ValidatorStatus.Completed + ) + ); + validatorManager.initiateValidatorWeightUpdate(validationID, 100); + } + + function testCompleteValidatorWeightUpdateUnauthorizedCaller() public { + vm.prank(address(0x123)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, address(0x123) + ) + ); + validatorManager.completeValidatorWeightUpdate(0); + } + + function testInitiateValidatorRemovalUnauthorizedCaller() public { + vm.prank(address(0x123)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, address(0x123) + ) + ); + validatorManager.initiateValidatorRemoval(bytes32(0)); + } + + function testCompleteValidatorRemovalUnauthorizedCaller() public { + vm.prank(address(0x123)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, address(0x123) + ) + ); + validatorManager.completeValidatorRemoval(0); + } + + function testValidatorManagerStorageSlot() public view { + assertEq( + _erc7201StorageSlot("ValidatorManager"), + validatorManager.VALIDATOR_MANAGER_STORAGE_LOCATION() + ); + } + + // Returns a 20-byte node ID + function _newNodeID() internal returns (bytes memory) { + nodeIDCounter++; + return abi.encodePacked(bytes20(sha256(new bytes(nodeIDCounter)))); + } + + function _setUpInitiateValidatorRegistration( + bytes memory nodeID, + bytes32 subnetID, + uint64 weight, + bytes memory blsPublicKey, + address rewardRecipient + ) internal returns (bytes32) { + uint64 registrationExpiry = uint64(block.timestamp) + 1 days; + + (bytes32 validationID, bytes memory registerL1ValidatorMessage) = ValidatorMessages + .packRegisterL1ValidatorMessage( + ValidatorMessages.ValidationPeriod({ + nodeID: nodeID, + subnetID: subnetID, + blsPublicKey: blsPublicKey, + registrationExpiry: registrationExpiry, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: weight + }) + ); + + bytes20 fixedID = _fixedNodeID(nodeID); + _mockSendWarpMessage(registerL1ValidatorMessage, bytes32(0)); + + _beforeSend(_weightToValue(weight), address(this)); + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit InitiatedValidatorRegistration( + validationID, fixedID, bytes32(0), registrationExpiry, weight + ); + + _beforeRegisterValidator(validationID, rewardRecipient); + _initiateValidatorRegistration({ + nodeID: nodeID, + blsPublicKey: blsPublicKey, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: weight, + rewardRecipient: rewardRecipient + }); + + return validationID; + } + + function _registerValidator( + bytes memory nodeID, + bytes32 subnetID, + uint64 weight, + bytes memory blsPublicKey, + uint64 registrationTimestamp, + address rewardRecipient + ) internal returns (bytes32 validationID) { + validationID = _setUpInitiateValidatorRegistration( + nodeID, subnetID, weight, blsPublicKey, rewardRecipient + ); + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, true); + + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + + vm.warp(registrationTimestamp); + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorRegistration(validationID, weight); + + _completeValidatorRegistration(0); + } + + function _initiateValidatorRemoval( + bytes32 validationID, + uint64 completionTimestamp, + bytes memory setWeightMessage, + bool includeUptime, + bytes memory uptimeMessage, + bool force + ) internal { + _mockSendWarpMessage(setWeightMessage, bytes32(0)); + if (includeUptime) { + _mockGetUptimeWarpMessage(uptimeMessage, true); + } + + vm.warp(completionTimestamp); + if (force) { + _forceInitiateValidatorRemoval(validationID, includeUptime); + } else { + _initiateValidatorRemoval(validationID, includeUptime); + } + } + + function _registerDefaultValidator() internal returns (bytes32 validationID) { + return _registerValidator({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + rewardRecipient: address(this) + }); + } + + function _registerDefaultValidatorWithRecipient( + address rewardRecipient + ) internal returns (bytes32 validationID) { + return _registerValidator({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + rewardRecipient: rewardRecipient + }); + } + + function _registerAndCompleteDefaultValidator() internal returns (bytes32 validationID) { + validationID = _registerDefaultValidator(); + bytes memory setWeightMessage = + ValidatorMessages.packL1ValidatorWeightMessage(validationID, 1, 0); + bytes memory uptimeMessage; + _initiateValidatorRemoval({ + validationID: validationID, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + setWeightMessage: setWeightMessage, + includeUptime: false, + uptimeMessage: uptimeMessage, + force: false + }); + + bytes memory l1ValidatorRegistrationMessage = + ValidatorMessages.packL1ValidatorRegistrationMessage(validationID, false); + + _mockGetPChainWarpMessage(l1ValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit CompletedValidatorRemoval(validationID); + + _completeValidatorRemoval(0); + } + + function _mockSendWarpMessage(bytes memory payload, bytes32 expectedMessageID) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(expectedMessageID) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.sendWarpMessage, payload) + ); + } + + function _mockGetPChainWarpMessage(bytes memory expectedPayload, bool valid) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: validatorManager.P_CHAIN_BLOCKCHAIN_ID(), + originSenderAddress: address(0), + payload: expectedPayload + }), + valid + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + } + + function _mockGetUptimeWarpMessage(bytes memory expectedPayload, bool valid) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(0), + payload: expectedPayload + }), + valid + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + } + + function _mockGetBlockchainID() internal { + _mockGetBlockchainID(DEFAULT_SOURCE_BLOCKCHAIN_ID); + } + + function _mockGetBlockchainID( + bytes32 blockchainID + ) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(blockchainID) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector) + ); + } + + function _mockInitializeValidatorSet( + bytes32 conversionID + ) internal { + _mockGetPChainWarpMessage( + ValidatorMessages.packSubnetToL1ConversionMessage(conversionID), true + ); + } + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight, + address rewardRecipient + ) internal virtual returns (bytes32); + + function _initiateValidatorRegistration( + bytes memory nodeID, + bytes memory blsPublicKey, + PChainOwner memory remainingBalanceOwner, + PChainOwner memory disableOwner, + uint64 weight + ) internal virtual returns (bytes32); + + function _completeValidatorRegistration( + uint32 messageIndex + ) internal virtual returns (bytes32); + + function _initiateValidatorRemoval(bytes32 validationID, bool includeUptime) internal virtual; + + function _forceInitiateValidatorRemoval( + bytes32 validationID, + bool includeUptime + ) internal virtual; + + function _completeValidatorRemoval( + uint32 messageIndex + ) internal virtual returns (bytes32); + + function _setUp() internal virtual returns (IACP99Manager); + + function _beforeSend(uint256 amount, address spender) internal virtual; + + function _beforeRegisterValidator( + bytes32 validationID, + address rewardRecipient + ) internal virtual; + + function _defaultConversionData() internal view returns (ConversionData memory) { + InitialValidator[] memory initialValidators = new InitialValidator[](2); + // The first initial validator has a high weight relative to the default PoS validator weight + // to avoid churn issues + initialValidators[0] = InitialValidator({ + nodeID: DEFAULT_INITIAL_VALIDATOR_NODE_ID_1, + weight: DEFAULT_INITIAL_VALIDATOR_WEIGHT, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + // The second initial validator has a low weight so that it can be safely removed in tests + initialValidators[1] = InitialValidator({ + nodeID: DEFAULT_INITIAL_VALIDATOR_NODE_ID_2, + weight: DEFAULT_WEIGHT, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + + // Confirm the total initial weight + uint64 initialWeight; + for (uint256 i = 0; i < initialValidators.length; i++) { + initialWeight += initialValidators[i].weight; + } + assertEq(initialWeight, DEFAULT_INITIAL_TOTAL_WEIGHT); + + return ConversionData({ + subnetID: DEFAULT_SUBNET_ID, + validatorManagerBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + validatorManagerAddress: address(validatorManager), + initialValidators: initialValidators + }); + } + + function _defaultConversionDataWeightsTooLow() internal view returns (ConversionData memory) { + InitialValidator[] memory initialValidators = new InitialValidator[](2); + + initialValidators[0] = InitialValidator({ + nodeID: DEFAULT_INITIAL_VALIDATOR_NODE_ID_1, + weight: 1, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + initialValidators[1] = InitialValidator({ + nodeID: DEFAULT_INITIAL_VALIDATOR_NODE_ID_2, + weight: 3, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + + return ConversionData({ + subnetID: DEFAULT_SUBNET_ID, + validatorManagerBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + validatorManagerAddress: address(validatorManager), + initialValidators: initialValidators + }); + } + + function _defaultConversionDataTotalWeight5() internal view returns (ConversionData memory) { + InitialValidator[] memory initialValidators = new InitialValidator[](2); + + initialValidators[0] = InitialValidator({ + nodeID: DEFAULT_INITIAL_VALIDATOR_NODE_ID_1, + weight: 1, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + initialValidators[1] = InitialValidator({ + nodeID: DEFAULT_INITIAL_VALIDATOR_NODE_ID_2, + weight: 4, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + + return ConversionData({ + subnetID: DEFAULT_SUBNET_ID, + validatorManagerBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + validatorManagerAddress: address(validatorManager), + initialValidators: initialValidators + }); + } + + // This needs to be kept in line with the contract conversions, but we can't make external calls + // to the contract and use vm.expectRevert at the same time. + // These are okay to use for PoA as well, because they're just used for conversions inside the tests. + function _valueToWeight( + uint256 value + ) internal pure returns (uint64) { + return uint64(value / 1e12); + } + + // This needs to be kept in line with the contract conversions, but we can't make external calls + // to the contract and use vm.expectRevert at the same time. + // These are okay to use for PoA as well, because they're just used for conversions inside the tests. + function _weightToValue( + uint64 weight + ) internal pure returns (uint256) { + return uint256(weight) * 1e12; + } + + function _defaultSettings( + address admin + ) internal pure returns (ValidatorManagerSettings memory) { + return ValidatorManagerSettings({ + admin: admin, + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }); + } + + function _erc7201StorageSlot( + bytes memory storageName + ) internal pure returns (bytes32) { + return keccak256( + abi.encode( + uint256(keccak256(abi.encodePacked("avalanche-icm.storage.", storageName))) - 1 + ) + ) & ~bytes32(uint256(0xff)); + } + + function _fixedNodeID( + bytes memory nodeID + ) internal pure returns (bytes20) { + bytes20 fixedID; + // solhint-disable-next-line no-inline-assembly + assembly { + fixedID := mload(add(nodeID, 32)) + } + return fixedID; + } +} +// solhint-enable no-empty-blocks diff --git a/icm-contracts/contracts/validator-manager/tests/ValidatorMessagesTests.t.sol b/icm-contracts/contracts/validator-manager/tests/ValidatorMessagesTests.t.sol new file mode 100644 index 000000000..8ab269999 --- /dev/null +++ b/icm-contracts/contracts/validator-manager/tests/ValidatorMessagesTests.t.sol @@ -0,0 +1,360 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: LicenseRef-Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; +import {PChainOwner, ConversionData, InitialValidator} from "../interfaces/IACP99Manager.sol"; + +contract ValidatorMessagesTest is Test { + bytes32 public constant DEFAULT_SUBNET_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes public constant DEFAULT_NODE_ID = + bytes(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes32 public constant DEFAULT_SUBNET_CONVERSION_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes public constant DEFAULT_BLS_PUBLIC_KEY = bytes( + hex"123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + ); + bytes32 public constant DEFAULT_VALIDATION_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + uint64 public constant DEFAULT_WEIGHT = 1e6; + address public constant DEFAULT_OWNER = 0x1234567812345678123456781234567812345678; + uint64 public constant REGISTRATION_EXPIRY_LENGTH = 1 days; + + // solhint-disable-next-line var-name-mixedcase + PChainOwner public DEFAULT_P_CHAIN_OWNER; + + function setUp() public { + address[] memory addresses = new address[](1); + addresses[0] = DEFAULT_OWNER; + DEFAULT_P_CHAIN_OWNER = PChainOwner({threshold: 1, addresses: addresses}); + } + + function testSubnetToL1ConversionMessageInvalidInputLength() public { + bytes memory packed = + ValidatorMessages.packSubnetToL1ConversionMessage(DEFAULT_SUBNET_CONVERSION_ID); + // Invalid length + bytes memory invalidPacked = new bytes(packed.length - 1); + for (uint256 i = 0; i < packed.length - 1; i++) { + invalidPacked[i] = packed[i]; + } + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidMessageLength.selector, 37, 38) + ); + ValidatorMessages.unpackSubnetToL1ConversionMessage(invalidPacked); + } + + function testSubnetToL1ConversionMessageInvalidCodecID() public { + bytes memory packed = + ValidatorMessages.packSubnetToL1ConversionMessage(DEFAULT_SUBNET_CONVERSION_ID); + + // Invalid codec ID + bytes memory invalidPacked2 = packed; + invalidPacked2[1] = 0x01; + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidCodecID.selector, uint32(1)) + ); + ValidatorMessages.unpackSubnetToL1ConversionMessage(invalidPacked2); + } + + function testSubnetToL1ConversionMessageInvalidTypeID() public { + bytes memory packed = + ValidatorMessages.packSubnetToL1ConversionMessage(DEFAULT_SUBNET_CONVERSION_ID); + // Invalid message type + bytes memory invalidPacked3 = packed; + invalidPacked3[5] = 0x01; + vm.expectRevert(ValidatorMessages.InvalidMessageType.selector); + ValidatorMessages.unpackSubnetToL1ConversionMessage(invalidPacked3); + } + + function testRegisterL1ValidatorMessageInvalidBLSKey() public { + vm.expectRevert(ValidatorMessages.InvalidBLSPublicKey.selector); + // 47 bytes + bytes memory invalidBLSKey = bytes( + hex"3456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + ); + ValidatorMessages.packRegisterL1ValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: DEFAULT_SUBNET_ID, + nodeID: DEFAULT_NODE_ID, + registrationExpiry: uint64(block.timestamp + REGISTRATION_EXPIRY_LENGTH), + blsPublicKey: invalidBLSKey, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }) + ); + } + + function testRegisterL1ValidatorMessageInvalidInputLength() public { + bytes memory packed = _getPackedRegisterL1ValidatorMessage(); + // Invalid length + bytes memory invalidPacked = new bytes(packed.length - 1); + for (uint256 i = 0; i < packed.length - 1; i++) { + invalidPacked[i] = packed[i]; + } + vm.expectRevert( + abi.encodeWithSelector( + ValidatorMessages.InvalidMessageLength.selector, uint32(193), uint32(194) + ) + ); + ValidatorMessages.unpackRegisterL1ValidatorMessage(invalidPacked); + } + + function testRegisterL1ValidatorMessageInvalidCodecID() public { + bytes memory packed = _getPackedRegisterL1ValidatorMessage(); + + // Invalid codec ID + bytes memory invalidPacked2 = packed; + invalidPacked2[1] = 0x01; + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidCodecID.selector, uint32(1)) + ); + ValidatorMessages.unpackRegisterL1ValidatorMessage(invalidPacked2); + } + + function testRegisterL1ValidatorMessageInvalidTypeID() public { + bytes memory packed = _getPackedRegisterL1ValidatorMessage(); + + // Invalid message type + bytes memory invalidPacked3 = packed; + invalidPacked3[5] = 0x00; + vm.expectRevert(ValidatorMessages.InvalidMessageType.selector); + ValidatorMessages.unpackRegisterL1ValidatorMessage(invalidPacked3); + } + + function testL1ValidatorRegistrationMessageInvalidInputLength() public { + bytes memory packed = + ValidatorMessages.packL1ValidatorRegistrationMessage(DEFAULT_VALIDATION_ID, true); + + // Invalid length + bytes memory invalidPacked = new bytes(packed.length - 1); + for (uint256 i = 0; i < packed.length - 1; i++) { + invalidPacked[i] = packed[i]; + } + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidMessageLength.selector, 38, 39) + ); + ValidatorMessages.unpackL1ValidatorRegistrationMessage(invalidPacked); + } + + function testL1ValidatorRegistrationMessageInvalidCodecID() public { + bytes memory packed = + ValidatorMessages.packL1ValidatorRegistrationMessage(DEFAULT_VALIDATION_ID, true); + + // Invalid codec ID + bytes memory invalidPacked2 = packed; + invalidPacked2[1] = 0x01; + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidCodecID.selector, uint32(1)) + ); + ValidatorMessages.unpackL1ValidatorRegistrationMessage(invalidPacked2); + } + + function testL1ValidatorRegistrationMessageInvalidTypeID() public { + bytes memory packed = + ValidatorMessages.packL1ValidatorRegistrationMessage(DEFAULT_VALIDATION_ID, true); + + // Invalid message type + bytes memory invalidPacked3 = packed; + invalidPacked3[5] = 0x01; + vm.expectRevert(ValidatorMessages.InvalidMessageType.selector); + ValidatorMessages.unpackL1ValidatorRegistrationMessage(invalidPacked3); + } + + function testValidationUptimeMessageInvalidInputLength() public { + bytes memory packed = + ValidatorMessages.packValidationUptimeMessage(DEFAULT_VALIDATION_ID, 100); + + // Invalid length + bytes memory invalidPacked = new bytes(packed.length - 1); + for (uint256 i = 0; i < packed.length - 1; i++) { + invalidPacked[i] = packed[i]; + } + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidMessageLength.selector, 45, 46) + ); + ValidatorMessages.unpackValidationUptimeMessage(invalidPacked); + } + + function testValidationUptimeMessageInvalidCodecID() public { + bytes memory packed = + ValidatorMessages.packValidationUptimeMessage(DEFAULT_VALIDATION_ID, 100); + + // Invalid codec ID + bytes memory invalidPacked2 = packed; + invalidPacked2[1] = 0x01; + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidCodecID.selector, uint32(1)) + ); + ValidatorMessages.unpackValidationUptimeMessage(invalidPacked2); + } + + function testValidationUptimeMessageInvalidTypeID() public { + bytes memory packed = + ValidatorMessages.packValidationUptimeMessage(DEFAULT_VALIDATION_ID, 100); + + // Invalid message type + bytes memory invalidPacked3 = packed; + invalidPacked3[5] = 0x01; + vm.expectRevert(ValidatorMessages.InvalidMessageType.selector); + ValidatorMessages.unpackValidationUptimeMessage(invalidPacked3); + } + + function testSetL1ValidatorWeightMessageInvalidInputLength() public { + bytes memory packed = ValidatorMessages.packL1ValidatorWeightMessage( + DEFAULT_VALIDATION_ID, 100, DEFAULT_WEIGHT + ); + + // Invalid length + bytes memory invalidPacked = new bytes(packed.length - 1); + for (uint256 i = 0; i < packed.length - 1; i++) { + invalidPacked[i] = packed[i]; + } + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidMessageLength.selector, 53, 54) + ); + ValidatorMessages.unpackL1ValidatorWeightMessage(invalidPacked); + } + + function testSetL1ValidatorWeightMessageInvalidCodecID() public { + bytes memory packed = ValidatorMessages.packL1ValidatorWeightMessage( + DEFAULT_VALIDATION_ID, 100, DEFAULT_WEIGHT + ); + + // Invalid codec ID + bytes memory invalidPacked2 = packed; + invalidPacked2[1] = 0x01; + vm.expectRevert( + abi.encodeWithSelector(ValidatorMessages.InvalidCodecID.selector, uint32(1)) + ); + ValidatorMessages.unpackL1ValidatorWeightMessage(invalidPacked2); + } + + function testSetL1ValidatorWeightMessageInvalidTypeID() public { + bytes memory packed = ValidatorMessages.packL1ValidatorWeightMessage( + DEFAULT_VALIDATION_ID, 100, DEFAULT_WEIGHT + ); + + // Invalid message type + bytes memory invalidPacked3 = packed; + invalidPacked3[5] = 0x01; + vm.expectRevert(ValidatorMessages.InvalidMessageType.selector); + ValidatorMessages.unpackL1ValidatorWeightMessage(invalidPacked3); + } + + function testRegisterL1ValidatorMessage() public view { + (bytes32 validationID, bytes memory packed) = ValidatorMessages + .packRegisterL1ValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: DEFAULT_SUBNET_ID, + nodeID: DEFAULT_NODE_ID, + registrationExpiry: uint64(block.timestamp + REGISTRATION_EXPIRY_LENGTH), + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }) + ); + + ValidatorMessages.ValidationPeriod memory info = + ValidatorMessages.unpackRegisterL1ValidatorMessage(packed); + assertEq(info.subnetID, DEFAULT_SUBNET_ID); + assertEq(info.nodeID, DEFAULT_NODE_ID); + assertEq(info.weight, DEFAULT_WEIGHT); + assertEq(info.registrationExpiry, uint64(block.timestamp + REGISTRATION_EXPIRY_LENGTH)); + assertEq(info.blsPublicKey, DEFAULT_BLS_PUBLIC_KEY); + assertEq(info.remainingBalanceOwner.threshold, DEFAULT_P_CHAIN_OWNER.threshold); + assertEq(info.remainingBalanceOwner.addresses[0], DEFAULT_P_CHAIN_OWNER.addresses[0]); + assertEq(info.disableOwner.threshold, DEFAULT_P_CHAIN_OWNER.threshold); + assertEq(info.disableOwner.addresses[0], DEFAULT_P_CHAIN_OWNER.addresses[0]); + + (bytes32 recoveredID,) = ValidatorMessages.packRegisterL1ValidatorMessage(info); + assertEq(recoveredID, validationID); + } + + function testSubnetToL1ConversionMessage() public pure { + bytes memory packed = + ValidatorMessages.packSubnetToL1ConversionMessage(DEFAULT_SUBNET_CONVERSION_ID); + bytes32 conversionID = ValidatorMessages.unpackSubnetToL1ConversionMessage(packed); + assertEq(conversionID, DEFAULT_SUBNET_CONVERSION_ID); + } + + function testPackL1ConversionData() public pure { + InitialValidator[] memory initialValidators = new InitialValidator[](1); + initialValidators[0] = InitialValidator({ + nodeID: DEFAULT_NODE_ID, + weight: DEFAULT_WEIGHT, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + bytes memory packed = ValidatorMessages.packConversionData( + ConversionData({ + subnetID: DEFAULT_SUBNET_ID, + validatorManagerBlockchainID: DEFAULT_SUBNET_CONVERSION_ID, + validatorManagerAddress: DEFAULT_OWNER, + initialValidators: initialValidators + }) + ); + + assertEq(packed.length, 186); + } + + function testL1ValidatorRegistrationMessage() public pure { + bytes memory packed = + ValidatorMessages.packL1ValidatorRegistrationMessage(DEFAULT_VALIDATION_ID, true); + (bytes32 validationID, bool registered) = + ValidatorMessages.unpackL1ValidatorRegistrationMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assert(registered); + } + + function testSetL1ValidatorWeightMessage() public pure { + bytes memory packed = ValidatorMessages.packL1ValidatorWeightMessage( + DEFAULT_VALIDATION_ID, 100, DEFAULT_WEIGHT + ); + (bytes32 validationID, uint64 nonce, uint64 weight) = + ValidatorMessages.unpackL1ValidatorWeightMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assertEq(nonce, 100); + assertEq(weight, DEFAULT_WEIGHT); + } + + function testL1ValidatorWeightMessage() public pure { + bytes memory packed = ValidatorMessages.packL1ValidatorWeightMessage( + DEFAULT_VALIDATION_ID, 100, DEFAULT_WEIGHT + ); + (bytes32 validationID, uint64 nonce, uint64 weight) = + ValidatorMessages.unpackL1ValidatorWeightMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assertEq(nonce, 100); + assertEq(weight, DEFAULT_WEIGHT); + } + + function testValidationUptimeMessage() public pure { + bytes memory packed = + ValidatorMessages.packValidationUptimeMessage(DEFAULT_VALIDATION_ID, 100); + (bytes32 validationID, uint64 uptime) = + ValidatorMessages.unpackValidationUptimeMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assertEq(uptime, 100); + } + + function _getPackedRegisterL1ValidatorMessage() internal view returns (bytes memory) { + (, bytes memory packed) = ValidatorMessages.packRegisterL1ValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: DEFAULT_SUBNET_ID, + nodeID: DEFAULT_NODE_ID, + registrationExpiry: uint64(block.timestamp + REGISTRATION_EXPIRY_LENGTH), + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + remainingBalanceOwner: DEFAULT_P_CHAIN_OWNER, + disableOwner: DEFAULT_P_CHAIN_OWNER, + weight: DEFAULT_WEIGHT + }) + ); + return packed; + } +} diff --git a/icm-contracts/lib/forge-std b/icm-contracts/lib/forge-std new file mode 160000 index 000000000..c28115db8 --- /dev/null +++ b/icm-contracts/lib/forge-std @@ -0,0 +1 @@ +Subproject commit c28115db8d90ebffb41953cf83aac63130f4bd40 diff --git a/icm-contracts/lib/openzeppelin-contracts-upgradeable b/icm-contracts/lib/openzeppelin-contracts-upgradeable new file mode 160000 index 000000000..723f8cab0 --- /dev/null +++ b/icm-contracts/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +Subproject commit 723f8cab09cdae1aca9ec9cc1cfa040c2d4b06c1 diff --git a/icm-contracts/resources/ERC20BridgeMultiHopDiagram.png b/icm-contracts/resources/ERC20BridgeMultiHopDiagram.png new file mode 100644 index 000000000..59cb6d59d Binary files /dev/null and b/icm-contracts/resources/ERC20BridgeMultiHopDiagram.png differ diff --git a/icm-contracts/resources/TeleporterDataFlowDiagram.png b/icm-contracts/resources/TeleporterDataFlowDiagram.png new file mode 100644 index 000000000..25ef36a49 Binary files /dev/null and b/icm-contracts/resources/TeleporterDataFlowDiagram.png differ diff --git a/icm-contracts/resources/TeleporterLogo.png b/icm-contracts/resources/TeleporterLogo.png new file mode 100644 index 000000000..84e68c29d Binary files /dev/null and b/icm-contracts/resources/TeleporterLogo.png differ diff --git a/icm-contracts/tests/flows/errors.go b/icm-contracts/tests/flows/errors.go new file mode 100644 index 000000000..9ba39996c --- /dev/null +++ b/icm-contracts/tests/flows/errors.go @@ -0,0 +1,5 @@ +package flows + +const ( + ErrTxReverted = "execution reverted" +) diff --git a/icm-contracts/tests/flows/governance/validator_set_sig.go b/icm-contracts/tests/flows/governance/validator_set_sig.go new file mode 100644 index 000000000..6302bab2b --- /dev/null +++ b/icm-contracts/tests/flows/governance/validator_set_sig.go @@ -0,0 +1,245 @@ +package governance + +import ( + "context" + "math/big" + + validatorsetsig "github.com/ava-labs/icm-services/abi-bindings/go/governance/ValidatorSetSig" + exampleerc20 "github.com/ava-labs/icm-services/abi-bindings/go/mocks/ExampleERC20" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func ValidatorSetSig(network *localnetwork.LocalNetwork) { + // ************************************************************************************************ + // Setup + // ************************************************************************************************ + // Deploy ValidatorSetSig expecting signatures from L1B instances to both L1s + // Deploy exampleERC20 instance to both L1s + // Construct ValidatorSetSig message with mock ERC20 as the target contract + // Create off-chain ICM messages using the ValidatorSetSig message to be signed by the L1B + // ************************************************************************************************ + // Test Case 1: validatorChain (L1B) != targetChain (L1A) + // ************************************************************************************************ + // Send the off-chain message to L1A instance of ValidatorSetSig and confirm it is accepted. + // Confirm the event is emitted + // Retry the same message and confirm it fails + // Send a new message with incremented nonce and confirm it is accepted. + // ************************************************************************************************ + // Test Case 2: validatorChain (L1B) == targetChain (L1B) + // ************************************************************************************************ + // Send a new message to L1B instance of ValidatorSetSig and confirm it is accepted + + // ************************************************************************************************ + // Setup + // ************************************************************************************************ + L1A, L1B := network.GetTwoL1s() + _, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy a ValidatorSetSigContract to L1A + validatorSetSigContractAddress, validatorSetSig := utils.DeployValidatorSetSig( + ctx, + fundedKey, + L1A, + L1B, + ) + // Deploy a ValidatorSetSigContract to L1B + validatorSetSigContractAddress2, validatorSetSig2 := utils.DeployValidatorSetSig( + ctx, + fundedKey, + L1B, + L1B, + ) + + // Deploy a mock ERC20 contract to L1A + exampleERC20ContractAddressA, exampleERC20A := utils.DeployExampleERC20( + ctx, + fundedKey, + L1A, + ) + + // Deploy a new example ERC20 contract this time to the same L1 as the validator. + exampleERC20ContractAddressB, exampleERC20B := utils.DeployExampleERC20( + ctx, + fundedKey, + L1B, + ) + + erc20ABI, err := exampleerc20.ExampleERC20MetaData.GetAbi() + Expect(err).Should(BeNil()) + + // Confirm that the validatorContract has a balance of 0 on the example erc20 contracts on both L1s + startingBalanceA, err := exampleERC20A.BalanceOf( + &bind.CallOpts{}, validatorSetSigContractAddress) + Expect(err).Should(BeNil()) + Expect(startingBalanceA.Cmp(big.NewInt(0))).Should(BeZero()) + + startingBalanceB, err := exampleERC20B.BalanceOf( + &bind.CallOpts{}, validatorSetSigContractAddress2) + Expect(err).Should(BeNil()) + Expect(startingBalanceB.Cmp(big.NewInt(0))).Should(BeZero()) + + // Construct a ValidatorSetSig message with mock ERC20 as the target contract + // and mint 100 tokens as the TxPayload + callData, err := erc20ABI.Pack("mint", validatorSetSigContractAddress, big.NewInt(100)) + Expect(err).Should(BeNil()) + + vssMessage1 := validatorsetsig.ValidatorSetSigMessage{ + ValidatorSetSigAddress: validatorSetSigContractAddress, + TargetContractAddress: exampleERC20ContractAddressA, + TargetBlockchainID: L1A.BlockchainID, + Nonce: big.NewInt(0), + Value: big.NewInt(0), + Payload: callData, + } + + // Construct a second ValidatorSetSig message with mock ERC20 as the target contract + // and mint 50 tokens as the TxPayload + callData2, err := erc20ABI.Pack("mint", validatorSetSigContractAddress, big.NewInt(50)) + Expect(err).Should(BeNil()) + vssMessage2 := validatorsetsig.ValidatorSetSigMessage{ + ValidatorSetSigAddress: validatorSetSigContractAddress, + TargetContractAddress: exampleERC20ContractAddressA, + TargetBlockchainID: L1A.BlockchainID, + Nonce: big.NewInt(1), + Value: big.NewInt(0), + Payload: callData2, + } + + // Create a message for the case where validatorSetSig contract and targetContract are on the same chain. + // Construct a ValidatorSetSig message with mock ERC20 as the target contract + // and mint 100 tokens as the TxPayload + callData3, err := erc20ABI.Pack("mint", validatorSetSigContractAddress2, big.NewInt(100)) + Expect(err).Should(BeNil()) + + vssMessage3 := validatorsetsig.ValidatorSetSigMessage{ + ValidatorSetSigAddress: validatorSetSigContractAddress2, + TargetContractAddress: exampleERC20ContractAddressB, + TargetBlockchainID: L1B.BlockchainID, + Nonce: big.NewInt(0), + Value: big.NewInt(0), + Payload: callData3, + } + + // Create chain config file with off-chain validatorsetsig message + networkID := network.GetNetworkID() + offchainMessages, icmEnabledChainConfigWithMsg := utils.InitOffChainMessageChainConfigValidatorSetSig( + networkID, + L1B, + validatorSetSigContractAddress, + []validatorsetsig.ValidatorSetSigMessage{vssMessage1, vssMessage2, vssMessage3}, + ) + + // Create chain config with off-chain messages + chainConfigs := make(utils.ChainConfigMap) + chainConfigs.Add(L1B, icmEnabledChainConfigWithMsg) + + // Restart nodes with new chain config + network.SetChainConfigs(chainConfigs) + + // ************************************************************************************************ + // Test Case 1: validatorChain (L1B) != targetChain (L1A) + // ************************************************************************************************ + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Execute the ValidatorSetSig executeCall and wait for acceptance + receipt := utils.ExecuteValidatorSetSigCallAndVerify( + ctx, + L1B, + L1A, + validatorSetSigContractAddress, + fundedKey, + &offchainMessages[0], + aggregator, + true, + ) + + // Confirm that the Delivered event is emitted and that validatorSetSig contract has a balance of 100 of ERC20 + deliveredEvent, err := utils.GetEventFromLogs(receipt.Logs, validatorSetSig.ParseDelivered) + Expect(err).Should(BeNil()) + Expect(deliveredEvent.TargetContractAddress).Should(Equal(exampleERC20ContractAddressA)) + Expect(deliveredEvent.Nonce.Cmp(big.NewInt(0))).Should(BeZero()) + + endingBalance, err := exampleERC20A.BalanceOf(nil, validatorSetSigContractAddress) + Expect(err).Should(BeNil()) + Expect(endingBalance).Should(Equal(big.NewInt(100))) + + // Resend the same message again and it should fail due to nonce being consumed + + _ = utils.ExecuteValidatorSetSigCallAndVerify( + ctx, + L1B, + L1A, + validatorSetSigContractAddress, + fundedKey, + &offchainMessages[0], + aggregator, + false, + ) + + // Confirm that the validatorSetSig contract still has a balance of 100 of ERC20 + endingBalance, err = exampleERC20A.BalanceOf(nil, validatorSetSigContractAddress) + Expect(err).Should(BeNil()) + Expect(endingBalance).Should(Equal(big.NewInt(100))) + + // Send another valid transaction with the incremented nonce + receipt2 := utils.ExecuteValidatorSetSigCallAndVerify( + ctx, + L1B, + L1A, + validatorSetSigContractAddress, + fundedKey, + &offchainMessages[1], + aggregator, + true, + ) + + // Confirm that the Delivered event is emitted and that validatorSetSig contract has a balance of 150 of ERC20 + deliveredEvent2, err := utils.GetEventFromLogs(receipt2.Logs, validatorSetSig.ParseDelivered) + Expect(err).Should(BeNil()) + Expect(deliveredEvent2.TargetContractAddress).Should(Equal(exampleERC20ContractAddressA)) + Expect(deliveredEvent2.Nonce).Should(Equal(big.NewInt(1))) + + endingBalance, err = exampleERC20A.BalanceOf(nil, validatorSetSigContractAddress) + Expect(err).Should(BeNil()) + Expect(endingBalance).Should(Equal(big.NewInt(150))) + + startingBalanceB, err = exampleERC20B.BalanceOf( + &bind.CallOpts{}, validatorSetSigContractAddress) + Expect(err).Should(BeNil()) + Expect(startingBalanceB.Cmp(big.NewInt(0))).Should(BeZero()) + + // ************************************************************************************************ + // Test Case 2: validatorChain (L1B) == targetChain (L1B) + // ************************************************************************************************ + + // Send the third transaction where the validatorSetSig contract expects validator signatures + // from the same chain that it is deployed on. + receipt3 := utils.ExecuteValidatorSetSigCallAndVerify( + ctx, + L1B, + L1B, + validatorSetSigContractAddress2, + fundedKey, + &offchainMessages[2], + aggregator, + true, + ) + + // Confirm that the Delivered event is emitted and that validatorSetSig2 contract has a balance + // of 100 of ERC20 + deliveredEvent3, err := utils.GetEventFromLogs(receipt3.Logs, validatorSetSig2.ParseDelivered) + Expect(err).Should(BeNil()) + Expect(deliveredEvent3.TargetContractAddress).Should(Equal(exampleERC20ContractAddressB)) + Expect(deliveredEvent.Nonce.Cmp(big.NewInt(0))).Should(BeZero()) + + endingBalance, err = exampleERC20B.BalanceOf(nil, validatorSetSigContractAddress2) + Expect(err).Should(BeNil()) + Expect(endingBalance).Should(Equal(big.NewInt(100))) +} diff --git a/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote.go b/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote.go new file mode 100644 index 000000000..054d505cf --- /dev/null +++ b/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote.go @@ -0,0 +1,194 @@ +package ictt + +import ( + "context" + "math/big" + + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + erc20tokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/** + * Deploy an ERC20TokenHome on the primary network + * Deploys ERC20TokenRemote to L1 A + * Transfers C-Chain example ERC20 tokens to L1 A + * Transfer tokens from L1 A to C-Chain + */ +func ERC20TokenHomeERC20TokenRemote(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an ExampleERC20 on the primary network as the token to be transferred + exampleERC20Address, exampleERC20 := utils.DeployExampleERC20Decimals( + ctx, + fundedKey, + cChainInfo, + erc20TokenHomeDecimals, + ) + + exampleERC20Decimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Create an ERC20TokenHome for transferring the ERC20 token + erc20TokenHomeAddress, erc20TokenHome := utils.DeployERC20TokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + exampleERC20Address, + exampleERC20Decimals, + ) + + // Token representation on L1 A will have same name, symbol, and decimals + tokenName, err := exampleERC20.Name(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenSymbol, err := exampleERC20.Symbol(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenDecimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Deploy an ERC20TokenRemote to L1 A + erc20TokenRemoteAddress, erc20TokenRemote := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1AInfo, + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + exampleERC20Decimals, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1AInfo, + erc20TokenRemoteAddress, + fundedKey, + aggregator, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Send tokens from C-Chain to recipient on L1 A + input := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenRemoteAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(13)) + + receipt, transferredAmount := utils.SendERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + input, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for message delivery + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckERC20TokenRemoteWithdrawal( + ctx, + erc20TokenRemote, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err := erc20TokenRemote.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + + // Transfer back to home chain + // Fund recipient with gas tokens on L1 A + utils.SendNativeTransfer( + ctx, + l1AInfo, + fundedKey, + recipientAddress, + big.NewInt(1e18), + ) + inputB := erc20tokenremote.SendTokensInput{ + DestinationBlockchainID: cChainInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenHomeAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: erc20TokenRemoteAddress, + PrimaryFee: big.NewInt(1e10), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + + receipt, transferredAmount = utils.SendERC20TokenRemote( + ctx, + l1AInfo, + erc20TokenRemote, + erc20TokenRemoteAddress, + inputB, + utils.BigIntSub(transferredAmount, inputB.PrimaryFee), + recipientKey, + ) + + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + cChainInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckERC20TokenHomeWithdrawal( + ctx, + erc20TokenHomeAddress, + exampleERC20, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err = exampleERC20.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) +} diff --git a/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote_multihop.go b/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote_multihop.go new file mode 100644 index 000000000..7415365c7 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote_multihop.go @@ -0,0 +1,208 @@ +package ictt + +import ( + "context" + "math/big" + + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/** + * Deploy a ERC20 token home on the primary network + * Deploys ERC20 token remote to L1 A and L1 B + * Transfers C-Chain example ERC20 tokens to L1 A + * Transfer tokens from L1 A to L1 B through multi-hop + * Transfer back tokens from L1 B to L1 A through multi-hop + */ +func ERC20TokenHomeERC20TokenRemoteMultiHop(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, l1BInfo := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an ExampleERC20 on L1 A as the token to be transferred + exampleERC20Address, exampleERC20 := utils.DeployExampleERC20Decimals( + ctx, + fundedKey, + cChainInfo, + erc20TokenHomeDecimals, + ) + + homeTokenDecimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Create an ERC20TokenHome for transferring the ERC20 token + erc20TokenHomeAddress, erc20TokenHome := utils.DeployERC20TokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + exampleERC20Address, + homeTokenDecimals, + ) + + // Token representation on L1s A and B will have same name, symbol, and decimals + tokenName, err := exampleERC20.Name(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenSymbol, err := exampleERC20.Symbol(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenDecimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Deploy an ERC20TokenRemote tp L1 A + erc20TokenRemoteAddressA, erc20TokenRemoteA := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1AInfo, + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + homeTokenDecimals, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + // Deploy an ERC20TokenRemote for L1 B + erc20TokenRemoteAddressB, erc20TokenRemoteB := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1BInfo, + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + homeTokenDecimals, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Register both ERC20TokenRemote instances on the ERC20TokenHome + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1AInfo, + erc20TokenRemoteAddressA, + fundedKey, + aggregator, + ) + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1BInfo, + erc20TokenRemoteAddressB, + fundedKey, + aggregator, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Send tokens from C-Chain to L1 A + input := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenRemoteAddressA, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(13)) + + receipt, transferredAmount := utils.SendERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + input, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for ERC20TokenRemote withdrawal + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckERC20TokenRemoteWithdrawal( + ctx, + erc20TokenRemoteA, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err := erc20TokenRemoteA.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + + // Multi-hop transfer to L1 B + transferredAmount = big.NewInt(0).Div(transferredAmount, big.NewInt(2)) + secondaryFeeAmount := big.NewInt(0).Div(transferredAmount, big.NewInt(4)) + utils.SendERC20TokenMultiHopAndVerify( + ctx, + teleporter, + fundedKey, + recipientKey, + recipientAddress, + l1AInfo, + erc20TokenRemoteA, + erc20TokenRemoteAddressA, + l1BInfo, + erc20TokenRemoteB, + erc20TokenRemoteAddressB, + cChainInfo, + transferredAmount, + secondaryFeeAmount, + aggregator, + ) + + // Multi-hop transfer back to L1 A + transferredAmount = big.NewInt(0).Sub(transferredAmount, secondaryFeeAmount) + secondaryFeeAmount = big.NewInt(0).Div(transferredAmount, big.NewInt(4)) + utils.SendERC20TokenMultiHopAndVerify( + ctx, + teleporter, + fundedKey, + recipientKey, + recipientAddress, + l1BInfo, + erc20TokenRemoteB, + erc20TokenRemoteAddressB, + l1AInfo, + erc20TokenRemoteA, + erc20TokenRemoteAddressA, + cChainInfo, + transferredAmount, + secondaryFeeAmount, + aggregator, + ) +} diff --git a/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote_send_and_call.go b/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote_send_and_call.go new file mode 100644 index 000000000..7bc0aee40 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/erc20_home_erc20_remote_send_and_call.go @@ -0,0 +1,282 @@ +package ictt + +import ( + "context" + "math/big" + + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + erc20tokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/** + * Deploy an ERC20TokenHome on the primary network + * Deploys ERC20TokenRemote to L1 A + * Transfers C-Chain example ERC20 tokens to L1 A and calls contract on L1 A using sendAndCall + * Transfers C-Chain example ERC20 to EOA on L1 A, and then transfer tokens from L1 A back + * C-Chain and calls contract on the C-Chain using sendAndCall + */ +func ERC20TokenHomeERC20TokenRemoteSendAndCall( + network *localnetwork.LocalNetwork, + teleporter utils.TeleporterTestInfo, +) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an ExampleERC20 on the primary network as the token to be transferred + exampleERC20Address, exampleERC20 := utils.DeployExampleERC20Decimals( + ctx, + fundedKey, + cChainInfo, + erc20TokenHomeDecimals, + ) + + exampleERC20Decimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Create an ERC20TokenHome for transferring the ERC20 token + erc20TokenHomeAddress, erc20TokenHome := utils.DeployERC20TokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + exampleERC20Address, + exampleERC20Decimals, + ) + + homeMockERC20SACRAddress, homeMockERC20SACR := utils.DeployMockERC20SendAndCallReceiver( + ctx, + fundedKey, + cChainInfo, + ) + + remoteMockERC20SACRAddress, remoteMockERC20SACR := utils.DeployMockERC20SendAndCallReceiver( + ctx, + fundedKey, + l1AInfo, + ) + + // Token representation on L1 A will have same name, symbol, and decimals + tokenName, err := exampleERC20.Name(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenSymbol, err := exampleERC20.Symbol(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenDecimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Deploy an ERC20TokenRemote to L1 A + erc20TokenRemoteAddress, erc20TokenRemote := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1AInfo, + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + exampleERC20Decimals, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1AInfo, + erc20TokenRemoteAddress, + fundedKey, + aggregator, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Generate new recipient to receive transferred tokens + fallbackKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + fallbackAddress := crypto.PubkeyToAddress(fallbackKey.PublicKey) + + amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(13)) + primaryFee := big.NewInt(1e18) + transferredAmount := utils.BigIntSub(amount, primaryFee) + + // Send tokens from C-Chain to Mock contract on L1 A + { + input := erc20tokenhome.SendAndCallInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenRemoteAddress, + RecipientContract: remoteMockERC20SACRAddress, + RecipientPayload: []byte{1}, + RequiredGasLimit: utils.BigIntMul(big.NewInt(10), utils.DefaultERC20RequiredGas), + RecipientGasLimit: utils.BigIntMul(big.NewInt(5), utils.DefaultERC20RequiredGas), + FallbackRecipient: fallbackAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + } + + receipt, transferredAmount := utils.SendAndCallERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + input, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for message delivery + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + event, err := utils.GetEventFromLogs(receipt.Logs, erc20TokenRemote.ParseCallSucceeded) + Expect(err).Should(BeNil()) + Expect(event.RecipientContract).Should(Equal(input.RecipientContract)) + Expect(event.Amount).Should(Equal(transferredAmount)) + + receiverEvent, err := utils.GetEventFromLogs(receipt.Logs, remoteMockERC20SACR.ParseTokensReceived) + Expect(err).Should(BeNil()) + Expect(receiverEvent.Amount).Should(Equal(transferredAmount)) + Expect(receiverEvent.Payload).Should(Equal(input.RecipientPayload)) + + // Check that the contract received the tokens + balance, err := erc20TokenRemote.BalanceOf(&bind.CallOpts{}, remoteMockERC20SACRAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + } + + // Transfer ERC20 tokens to account on L1 A + { + // Send ERC20 tokens from C-Chain to recipient on L1 A + input := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenRemoteAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + + receipt, transferredAmount := utils.SendERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + input, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for message delivery + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckERC20TokenRemoteWithdrawal( + ctx, + erc20TokenRemote, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err := erc20TokenRemote.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + } + + // Send tokens to mock contract on C-Chain using sendAndCall + { + // Fund recipient with gas tokens on L1 A + utils.SendNativeTransfer( + ctx, + l1AInfo, + fundedKey, + recipientAddress, + big.NewInt(1e18), + ) + + inputB := erc20tokenremote.SendAndCallInput{ + DestinationBlockchainID: cChainInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenHomeAddress, + RecipientContract: homeMockERC20SACRAddress, + RecipientPayload: []byte{1}, + RequiredGasLimit: utils.BigIntMul(big.NewInt(10), utils.DefaultERC20RequiredGas), + RecipientGasLimit: utils.BigIntMul(big.NewInt(5), utils.DefaultERC20RequiredGas), + FallbackRecipient: fallbackAddress, + PrimaryFeeTokenAddress: erc20TokenRemoteAddress, + PrimaryFee: big.NewInt(1e10), + SecondaryFee: big.NewInt(0), + } + + receipt, transferredAmount := utils.SendAndCallERC20TokenRemote( + ctx, + l1AInfo, + erc20TokenRemote, + erc20TokenRemoteAddress, + inputB, + utils.BigIntSub(transferredAmount, inputB.PrimaryFee), + recipientKey, + ) + + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + cChainInfo, + true, + fundedKey, + nil, + aggregator, + ) + + homeEvent, err := utils.GetEventFromLogs(receipt.Logs, erc20TokenHome.ParseCallSucceeded) + Expect(err).Should(BeNil()) + Expect(homeEvent.RecipientContract).Should(Equal(inputB.RecipientContract)) + Expect(homeEvent.Amount).Should(Equal(transferredAmount)) + + receiverEvent, err := utils.GetEventFromLogs(receipt.Logs, homeMockERC20SACR.ParseTokensReceived) + Expect(err).Should(BeNil()) + Expect(receiverEvent.Amount).Should(Equal(transferredAmount)) + Expect(receiverEvent.Payload).Should(Equal(inputB.RecipientPayload)) + + // Check that the recipient received the tokens + balance, err := exampleERC20.BalanceOf(&bind.CallOpts{}, homeMockERC20SACRAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + } +} diff --git a/icm-contracts/tests/flows/ictt/erc20_home_native_remote.go b/icm-contracts/tests/flows/ictt/erc20_home_native_remote.go new file mode 100644 index 000000000..d8083f6d8 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/erc20_home_native_remote.go @@ -0,0 +1,198 @@ +package ictt + +import ( + "context" + "math/big" + + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + nativetokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/NativeTokenRemote" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +var ( + decimalsShift = uint8(1) + tokenMultiplier = utils.GetTokenMultiplier(decimalsShift) + initialReserveImbalance = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)) + + // These two should be changed together + multiplyOnRemote = true + erc20TokenHomeDecimals = utils.NativeTokenDecimals - decimalsShift + + burnedFeesReportingRewardPercentage = big.NewInt(1) +) + +/** + * Deploy a ERC20Token on the primary network + * Deploys NativeTokenRemote to L1 A and L1 B + * Transfers C-Chain example ERC20 tokens to L1 A as L1 A's native token + * Transfer back tokens from L1 A to C-Chain + */ +func ERC20TokenHomeNativeTokenRemote(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an ExampleERC20 on L1 A as the token to be transferred + exampleERC20Address, exampleERC20 := utils.DeployExampleERC20Decimals( + ctx, + fundedKey, + cChainInfo, + erc20TokenHomeDecimals, + ) + + exampleERC20Decimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Create an ERC20TokenHome for transferring the ERC20 token + erc20TokenHomeAddress, erc20TokenHome := utils.DeployERC20TokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + exampleERC20Address, + exampleERC20Decimals, + ) + + // Deploy a NativeTokenRemote to L1 A + nativeTokenRemoteAddressA, nativeTokenRemoteA := utils.DeployNativeTokenRemote( + ctx, + teleporter, + l1AInfo, + "SUBA", + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + exampleERC20Decimals, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + collateralAmount := utils.RegisterTokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1AInfo, + nativeTokenRemoteAddressA, + initialReserveImbalance, + utils.GetTokenMultiplier(decimalsShift), + multiplyOnRemote, + fundedKey, + aggregator, + ) + + utils.AddCollateralToERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + l1AInfo.BlockchainID, + nativeTokenRemoteAddressA, + collateralAmount, + fundedKey, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + recipientKey.ECDH() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Send tokens from C-Chain to L1 A + input := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenRemoteAddressA, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) + receipt, transferredAmount := utils.SendERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + input, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for a native token mint withdrawal + teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Verify the recipient received the tokens + utils.CheckBalance(ctx, recipientAddress, transferredAmount, l1AInfo.RPCClient) + + // Send back to the home chain and check that ERC20TokenHome received the tokens + input_A := nativetokenremote.SendTokensInput{ + DestinationBlockchainID: cChainInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenHomeAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: nativeTokenRemoteAddressA, + PrimaryFee: big.NewInt(1e10), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + // Send half of the received amount to account for gas expenses + amountToSendA := new(big.Int).Div(transferredAmount, big.NewInt(2)) + receipt, transferredAmount = utils.SendNativeTokenRemote( + ctx, + l1AInfo, + nativeTokenRemoteA, + nativeTokenRemoteAddressA, + input_A, + amountToSendA, + recipientKey, + ) + + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + cChainInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Check that the recipient received the tokens + scaledAmount := utils.RemoveTokenScaling(tokenMultiplier, multiplyOnRemote, transferredAmount) + utils.CheckERC20TokenHomeWithdrawal( + ctx, + erc20TokenHomeAddress, + exampleERC20, + receipt, + recipientAddress, + scaledAmount, + ) + + // Check that the recipient received the tokens + balance, err := exampleERC20.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(scaledAmount)) +} diff --git a/icm-contracts/tests/flows/ictt/erc20_home_native_remote_multihop.go b/icm-contracts/tests/flows/ictt/erc20_home_native_remote_multihop.go new file mode 100644 index 000000000..89c819687 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/erc20_home_native_remote_multihop.go @@ -0,0 +1,259 @@ +package ictt + +import ( + "context" + "math/big" + + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/* +* + - Deploy a ERC20TokenHome on the primary network + - Deploys NativeTokenRemote toA and L1 B + - Transfers C-Chain example ERC20 tokens to L1 A as L1 A's native token + - Transfers C-Chain example ERC20 tokens to L1 B as L1 B's native token + to collateralize the token transferrer on L1 B + - Transfer tokens from L1 A to L1 B through multi-hop + - Transfer back tokens from L1 B to L1 A through multi-hop +*/ +func ERC20TokenHomeNativeTokenRemoteMultiHop(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, l1BInfo := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an ExampleERC20 on L1 A as the token to be transferred + exampleERC20Address, exampleERC20 := utils.DeployExampleERC20Decimals( + ctx, + fundedKey, + cChainInfo, + erc20TokenHomeDecimals, + ) + + exampleERC20Decimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + erc20TokenHomeAddress, erc20TokenHome := utils.DeployERC20TokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + exampleERC20Address, + exampleERC20Decimals, + ) + + // Deploy a NativeTokenRemote to L1 A + nativeTokenRemoteAddressA, nativeTokenRemoteA := utils.DeployNativeTokenRemote( + ctx, + teleporter, + l1AInfo, + "SUBA", + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + exampleERC20Decimals, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + + // Deploy a NativeTokenRemote to L1 B + nativeTokenRemoteAddressB, nativeTokenRemoteB := utils.DeployNativeTokenRemote( + ctx, + teleporter, + l1BInfo, + "SUBB", + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + exampleERC20Decimals, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Register both NativeTokenDestinations on the ERC20TokenHome + collateralAmountA := utils.RegisterTokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1AInfo, + nativeTokenRemoteAddressA, + initialReserveImbalance, + utils.GetTokenMultiplier(decimalsShift), + multiplyOnRemote, + fundedKey, + aggregator, + ) + + collateralAmountB := utils.RegisterTokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1BInfo, + nativeTokenRemoteAddressB, + initialReserveImbalance, + utils.GetTokenMultiplier(decimalsShift), + multiplyOnRemote, + fundedKey, + aggregator, + ) + + // Add collateral for both NativeTokenDestinations + utils.AddCollateralToERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + l1AInfo.BlockchainID, + nativeTokenRemoteAddressA, + collateralAmountA, + fundedKey, + ) + + utils.AddCollateralToERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + l1BInfo.BlockchainID, + nativeTokenRemoteAddressB, + collateralAmountB, + fundedKey, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // These are set during the initial transferring, and used in the multi-hop transfers + amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) + + // Send tokens from C-Chain to L1 A + inputA := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenRemoteAddressA, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + receipt, transferredAmountA := utils.SendERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + inputA, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for a native token mint withdrawal + teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Verify the recipient received the tokens + utils.CheckBalance(ctx, recipientAddress, transferredAmountA, l1AInfo.RPCClient) + + // Send tokens from C-Chain to L1 B + inputB := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenRemoteAddressB, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + receipt, transferredAmountB := utils.SendERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + inputB, + amount, + fundedKey, + ) + + // Relay the message to L1 B and check for a native token mint withdrawal + teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Verify the recipient received the tokens + utils.CheckBalance(ctx, recipientAddress, transferredAmountB, l1BInfo.RPCClient) + + // Multi-hop transfer to L1 B + // Send half of the received amount to account for gas expenses + amountToSend := new(big.Int).Div(transferredAmountA, big.NewInt(2)) + + utils.SendNativeMultiHopAndVerify( + ctx, + teleporter, + fundedKey, + recipientAddress, + l1AInfo, + nativeTokenRemoteA, + nativeTokenRemoteAddressA, + l1BInfo, + nativeTokenRemoteB, + nativeTokenRemoteAddressB, + cChainInfo, + amountToSend, + big.NewInt(0), + aggregator, + ) + + // Multi-hop transfer back to L1 A + secondaryFeeAmount := new(big.Int).Div(amountToSend, big.NewInt(4)) + utils.SendNativeMultiHopAndVerify( + ctx, + teleporter, + fundedKey, + recipientAddress, + l1BInfo, + nativeTokenRemoteB, + nativeTokenRemoteAddressB, + l1AInfo, + nativeTokenRemoteA, + nativeTokenRemoteAddressA, + cChainInfo, + amountToSend, + secondaryFeeAmount, + aggregator, + ) +} diff --git a/icm-contracts/tests/flows/ictt/errors.go b/icm-contracts/tests/flows/ictt/errors.go new file mode 100644 index 000000000..125fbfeb6 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/errors.go @@ -0,0 +1,6 @@ +package ictt + +const ( + ErrRemoteNotRegistered = "remote not registered" + ErrNonZeroCollateralNeeded = "collateral needed for remote" +) diff --git a/icm-contracts/tests/flows/ictt/native_home_erc20_remote.go b/icm-contracts/tests/flows/ictt/native_home_erc20_remote.go new file mode 100644 index 000000000..deba48e4e --- /dev/null +++ b/icm-contracts/tests/flows/ictt/native_home_erc20_remote.go @@ -0,0 +1,188 @@ +package ictt + +import ( + "context" + "math/big" + + nativetokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/NativeTokenHome" + erc20tokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/** + * Deploy a NativeTokenHome on the primary network + * Deploys ERC20TokenRemote to L1 A + * Transfers C-Chain native tokens to L1 A + * Transfer back tokens from L1 A to C-Chain + */ +func NativeTokenHomeERC20TokenRemote(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an example WAVAX on the primary network + wavaxAddress, wavax := utils.DeployWrappedNativeToken( + ctx, + fundedKey, + cChainInfo, + "AVAX", + ) + + // Create a NativeTokenHome for transferring the native token + nativeTokenHomeAddress, nativeTokenHome := utils.DeployNativeTokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + wavaxAddress, + ) + + // Token representation on L1 A will have same name, symbol, and decimals + tokenName, err := wavax.Name(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenSymbol, err := wavax.Symbol(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenDecimals, err := wavax.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Deploy an ERC20TokenRemote to L1 A + erc20TokenRemoteAddress, erc20TokenRemote := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1AInfo, + fundedAddress, + cChainInfo.BlockchainID, + nativeTokenHomeAddress, + 18, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + nativeTokenHomeAddress, + l1AInfo, + erc20TokenRemoteAddress, + fundedKey, + aggregator, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Send tokens from C-Chain to recipient on L1 A + input := nativetokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenRemoteAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: wavaxAddress, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + + // Send the tokens and verify expected events + amount := big.NewInt(2e18) + receipt, transferredAmount := utils.SendNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + wavax, + input, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for message delivery + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckERC20TokenRemoteWithdrawal( + ctx, + erc20TokenRemote, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err := erc20TokenRemote.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + + // Fund recipient with gas tokens on L1 A + utils.SendNativeTransfer( + ctx, + l1AInfo, + fundedKey, + recipientAddress, + big.NewInt(1e18), + ) + inputA := erc20tokenremote.SendTokensInput{ + DestinationBlockchainID: cChainInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenHomeAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: erc20TokenRemoteAddress, + PrimaryFee: big.NewInt(1e10), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + // Send tokens on L1 A back for native tokens on C-Chain + receipt, transferredAmount = utils.SendERC20TokenRemote( + ctx, + l1AInfo, + erc20TokenRemote, + erc20TokenRemoteAddress, + inputA, + utils.BigIntSub(transferredAmount, inputA.PrimaryFee), + recipientKey, + ) + + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + cChainInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Check that the recipient received the tokens + utils.CheckNativeTokenHomeWithdrawal( + ctx, + nativeTokenHomeAddress, + wavax, + receipt, + transferredAmount, + ) + + utils.CheckBalance(ctx, recipientAddress, transferredAmount, cChainInfo.RPCClient) +} diff --git a/icm-contracts/tests/flows/ictt/native_home_erc20_remote_multihop.go b/icm-contracts/tests/flows/ictt/native_home_erc20_remote_multihop.go new file mode 100644 index 000000000..861d95d22 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/native_home_erc20_remote_multihop.go @@ -0,0 +1,183 @@ +package ictt + +import ( + "context" + "math/big" + + nativetokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/NativeTokenHome" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + + . "github.com/onsi/gomega" +) + +/** + * Deploy a NativeTokenHome on the primary network + * Deploys ERC20TokenRemote to L1 A and L1 B + * Transfers C-Chain native tokens to L1 A + * Transfer tokens from L1 A to L1 B through multi-hop + * Brige back tokens from L1 B to L1 A through multi-hop + */ +func NativeTokenHomeERC20TokenRemoteMultiHop(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, l1BInfo := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy a NativeTokenHome on the primary network + wavaxAddress, wavax := utils.DeployWrappedNativeToken( + ctx, + fundedKey, + cChainInfo, + "AVAX", + ) + nativeTokenHomeAddress, nativeTokenHome := utils.DeployNativeTokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + wavaxAddress, + ) + + // Token representation on L1 B will have same name, symbol, and decimals + tokenName, err := wavax.Name(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenSymbol, err := wavax.Symbol(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenDecimals, err := wavax.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + // Deploy an ERC20TokenRemote on L1 A + erc20TokenRemoteAddressA, erc20TokenRemoteA := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1AInfo, + fundedAddress, + cChainInfo.BlockchainID, + nativeTokenHomeAddress, + 18, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + // Deploy an ERC20TokenRemote on L1 B + erc20TokenRemoteAddressB, erc20TokenRemoteB := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1BInfo, + fundedAddress, + cChainInfo.BlockchainID, + nativeTokenHomeAddress, + 18, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Register both ERC20Destinations on the NativeTokenHome + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + nativeTokenHomeAddress, + l1AInfo, + erc20TokenRemoteAddressA, + fundedKey, + aggregator, + ) + + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + nativeTokenHomeAddress, + l1BInfo, + erc20TokenRemoteAddressB, + fundedKey, + aggregator, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Send tokens from C-Chain to recipient on L1 A + input := nativetokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenRemoteAddressA, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: wavaxAddress, + PrimaryFee: big.NewInt(1e10), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + + // Send the tokens and verify expected events + amount := big.NewInt(2e18) + receipt, transferredAmount := utils.SendNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + wavax, + input, + utils.BigIntSub(amount, input.PrimaryFee), + fundedKey, + ) + + // Relay the message to L1 B and check for message delivery + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckERC20TokenRemoteWithdrawal( + ctx, + erc20TokenRemoteA, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err := erc20TokenRemoteA.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + + // Send tokens from L1 A to recipient on L1 B through a multi-hop + secondaryFeeAmount := new(big.Int).Div(transferredAmount, big.NewInt(4)) + utils.SendERC20TokenMultiHopAndVerify( + ctx, + teleporter, + fundedKey, + recipientKey, + recipientAddress, + l1AInfo, + erc20TokenRemoteA, + erc20TokenRemoteAddressA, + l1BInfo, + erc20TokenRemoteB, + erc20TokenRemoteAddressB, + cChainInfo, + transferredAmount, + secondaryFeeAmount, + aggregator, + ) +} diff --git a/icm-contracts/tests/flows/ictt/native_home_native_remote.go b/icm-contracts/tests/flows/ictt/native_home_native_remote.go new file mode 100644 index 000000000..e0eef4d84 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/native_home_native_remote.go @@ -0,0 +1,185 @@ +package ictt + +import ( + "context" + "math/big" + + nativetokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/NativeTokenHome" + nativetokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/NativeTokenRemote" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + . "github.com/onsi/gomega" +) + +/** + * Deploy a NativeTokenHome on the primary network + * Deploys a NativeTokenRemote to L1 A + * Transfers C-Chain native tokens to L1 A + * Transfer back tokens from L1 A to C-Chain + */ +func NativeTokenHomeNativeDestination(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an example WAVAX on the primary network + cChainWAVAXAddress, wavax := utils.DeployWrappedNativeToken( + ctx, + fundedKey, + cChainInfo, + "AVAX", + ) + + // Create a NativeTokenHome on the primary network + nativeTokenHomeAddress, nativeTokenHome := utils.DeployNativeTokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + cChainWAVAXAddress, + ) + + // Deploy a NativeTokenRemote to L1 A + nativeTokenRemoteAddress, nativeTokenRemote := utils.DeployNativeTokenRemote( + ctx, + teleporter, + l1AInfo, + "SUBA", + fundedAddress, + cChainInfo.BlockchainID, + nativeTokenHomeAddress, + 18, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Register the NativeTokenRemote on the NativeTokenHome + collateralAmount := utils.RegisterTokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + nativeTokenHomeAddress, + l1AInfo, + nativeTokenRemoteAddress, + initialReserveImbalance, + big.NewInt(1), + multiplyOnRemote, + fundedKey, + aggregator, + ) + + utils.AddCollateralToNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + l1AInfo.BlockchainID, + nativeTokenRemoteAddress, + collateralAmount, + fundedKey, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Send tokens from C-Chain to recipient on L1 A that fully collateralize token transferrer with leftover tokens. + amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(13)) + { + input := nativetokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenRemoteAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: cChainWAVAXAddress, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + // Send initialReserveImbalance tokens to fully collateralize token transferrer and mint the remainder. + receipt, _ := utils.SendNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + wavax, + input, + amount, + fundedKey, + ) + + teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckBalance( + ctx, + recipientAddress, + amount, + l1AInfo.RPCClient, + ) + } + + // Send tokens on L1 A back for native tokens on C-Chain + { + input_A := nativetokenremote.SendTokensInput{ + DestinationBlockchainID: cChainInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenHomeAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: nativeTokenRemoteAddress, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + // Send half of the tokens back to C-Chain + amount := big.NewInt(0).Div(amount, big.NewInt(2)) + receipt, transferredAmount := utils.SendNativeTokenRemote( + ctx, + l1AInfo, + nativeTokenRemote, + nativeTokenRemoteAddress, + input_A, + amount, + recipientKey, + ) + + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + cChainInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Check that the recipient received the tokens + homeAmount := transferredAmount + utils.CheckNativeTokenHomeWithdrawal( + ctx, + nativeTokenHomeAddress, + wavax, + receipt, + homeAmount, + ) + + utils.CheckBalance(ctx, recipientAddress, homeAmount, cChainInfo.RPCClient) + } +} diff --git a/icm-contracts/tests/flows/ictt/native_home_native_remote_multihop.go b/icm-contracts/tests/flows/ictt/native_home_native_remote_multihop.go new file mode 100644 index 000000000..529d80108 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/native_home_native_remote_multihop.go @@ -0,0 +1,257 @@ +package ictt + +import ( + "context" + "math/big" + + nativetokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/NativeTokenHome" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + . "github.com/onsi/gomega" +) + +/* +* + - Deploy a NativeTokenHome on the primary network + - Deploys NativeTokenRemote to L1 A and L1 B + - Transfers native tokens from the C-Chain to L1 A as L1 A's native token + - Transfers native tokens from the C-Chain to L1 B as L1 B's native token + to collateralize the L1 B token transferrer + - Transfer tokens from L1 A to L1 B through multi-hop + - Transfer back tokens from L1 B to L1 A through multi-hop +*/ +func NativeTokenHomeNativeTokenRemoteMultiHop(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, l1BInfo := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // decimalsShift is always 0 for native to native + decimalsShift := uint8(0) + + // Deploy an example WAVAX on the primary network + wavaxAddress, wavax := utils.DeployWrappedNativeToken( + ctx, + fundedKey, + cChainInfo, + "AVAX", + ) + + // Create a NativeTokenHome on the primary network + nativeTokenHomeAddress, nativeTokenHome := utils.DeployNativeTokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + wavaxAddress, + ) + + // Deploy a NativeTokenRemote to L1 A + nativeTokenRemoteAddressA, nativeTokenRemoteA := utils.DeployNativeTokenRemote( + ctx, + teleporter, + l1AInfo, + "SUBA", + fundedAddress, + cChainInfo.BlockchainID, + nativeTokenHomeAddress, + utils.NativeTokenDecimals, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + + // Deploy a NativeTokenRemote to L1 B + nativeTokenRemoteAddressB, nativeTokenRemoteB := utils.DeployNativeTokenRemote( + ctx, + teleporter, + l1BInfo, + "SUBB", + fundedAddress, + cChainInfo.BlockchainID, + nativeTokenHomeAddress, + utils.NativeTokenDecimals, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Register both NativeTokenDestinations on the NativeTokenHome + collateralAmountA := utils.RegisterTokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + nativeTokenHomeAddress, + l1AInfo, + nativeTokenRemoteAddressA, + initialReserveImbalance, + utils.GetTokenMultiplier(decimalsShift), + multiplyOnRemote, + fundedKey, + aggregator, + ) + + collateralAmountB := utils.RegisterTokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + nativeTokenHomeAddress, + l1BInfo, + nativeTokenRemoteAddressB, + initialReserveImbalance, + utils.GetTokenMultiplier(decimalsShift), + multiplyOnRemote, + fundedKey, + aggregator, + ) + + // Add collateral for both NativeTokenDestinations + utils.AddCollateralToNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + l1AInfo.BlockchainID, + nativeTokenRemoteAddressA, + collateralAmountA, + fundedKey, + ) + + utils.AddCollateralToNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + l1BInfo.BlockchainID, + nativeTokenRemoteAddressB, + collateralAmountB, + fundedKey, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) + + // Send tokens from C-Chain to L1 A + inputA := nativetokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenRemoteAddressA, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: wavaxAddress, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + receipt, transferredAmountA := utils.SendNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + wavax, + inputA, + amount, + fundedKey, + ) + + // Relay the message to L1 A and check for a native token mint withdrawal + teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Verify the recipient received the tokens + utils.CheckBalance(ctx, recipientAddress, transferredAmountA, l1AInfo.RPCClient) + + // Send tokens from C-Chain to L1 B + inputB := nativetokenhome.SendTokensInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenRemoteAddressB, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: wavaxAddress, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + receipt, transferredAmountB := utils.SendNativeTokenHome( + ctx, + cChainInfo, + nativeTokenHome, + nativeTokenHomeAddress, + wavax, + inputB, + amount, + fundedKey, + ) + + // Relay the message to L1 B and check for a native token mint withdrawal + teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Verify the recipient received the tokens + utils.CheckBalance(ctx, recipientAddress, transferredAmountB, l1BInfo.RPCClient) + + // Multi-hop transfer to L1 B + // Send half of the received amount to account for gas expenses + amountToSendA := new(big.Int).Div(transferredAmountA, big.NewInt(2)) + + utils.SendNativeMultiHopAndVerify( + ctx, + teleporter, + fundedKey, + recipientAddress, + l1AInfo, + nativeTokenRemoteA, + nativeTokenRemoteAddressA, + l1BInfo, + nativeTokenRemoteB, + nativeTokenRemoteAddressB, + cChainInfo, + amountToSendA, + big.NewInt(0), + aggregator, + ) + + // Again, send half of the received amount to account for gas expenses + amountToSendB := new(big.Int).Div(amountToSendA, big.NewInt(2)) + secondaryFeeAmount := new(big.Int).Div(amountToSendB, big.NewInt(4)) + + // Multi-hop transfer back to L1 A + utils.SendNativeMultiHopAndVerify( + ctx, + teleporter, + fundedKey, + recipientAddress, + l1BInfo, + nativeTokenRemoteB, + nativeTokenRemoteAddressB, + l1AInfo, + nativeTokenRemoteA, + nativeTokenRemoteAddressA, + cChainInfo, + amountToSendB, + secondaryFeeAmount, + aggregator, + ) +} diff --git a/icm-contracts/tests/flows/ictt/registration_and_collateral_check.go b/icm-contracts/tests/flows/ictt/registration_and_collateral_check.go new file mode 100644 index 000000000..219f42cbc --- /dev/null +++ b/icm-contracts/tests/flows/ictt/registration_and_collateral_check.go @@ -0,0 +1,201 @@ +package ictt + +import ( + "context" + "math/big" + + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/** + * Deploys an ERC20TokenHome contract on the C-Chain + * Deploys an ERC20TokenRemote contract on L1 A + * Check sending to unregistered remote fails + * Register the ERC20TokenRemote to home contract + * Check sending to non-collateralized remote fails + * Collateralize the remote + * Check sending to collateralized remote succeeds and withdraws with correct scale. + */ +func RegistrationAndCollateralCheck(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an ExampleERC20 on L1 A as the token to be transferred + exampleERC20Address, exampleERC20 := utils.DeployExampleERC20Decimals( + ctx, + fundedKey, + cChainInfo, + erc20TokenHomeDecimals, + ) + + // Create an ERC20TokenHome for transferring the ERC20 token + erc20TokenHomeAddress, erc20TokenHome := utils.DeployERC20TokenHome( + ctx, + teleporter, + fundedKey, + cChainInfo, + fundedAddress, + exampleERC20Address, + erc20TokenHomeDecimals, + ) + + // Deploy a NativeTokenRemote to L1 A + nativeTokenRemoteAddressA, _ := utils.DeployNativeTokenRemote( + ctx, + teleporter, + l1AInfo, + "SUBA", + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + erc20TokenHomeDecimals, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + // Send tokens from C-Chain to L1 A + input := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: nativeTokenRemoteAddressA, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultNativeTokenRequiredGas, + } + + amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) + + initialBalance, err := exampleERC20.BalanceOf(&bind.CallOpts{}, erc20TokenHomeAddress) + Expect(err).Should(BeNil()) + + // Send the tokens and expect for failure since TokenRemote instance is not registered. + optsA, err := bind.NewKeyedTransactorWithChainID(fundedKey, cChainInfo.EVMChainID) + Expect(err).Should(BeNil()) + _, err = erc20TokenHome.Send( + optsA, + input, + amount, + ) + Expect(err).Should(Not(BeNil())) + Expect(err.Error()).Should(ContainSubstring(ErrRemoteNotRegistered)) + + // Check the balance of the ERC20TokenHome to ensure it was not changed + balance, err := exampleERC20.BalanceOf(&bind.CallOpts{}, erc20TokenHomeAddress) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(balance, initialBalance) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Register the NativeTokenRemote to the ERC20TokenHome + collateralNeeded := utils.RegisterTokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1AInfo, + nativeTokenRemoteAddressA, + initialReserveImbalance, + utils.GetTokenMultiplier(decimalsShift), + multiplyOnRemote, + fundedKey, + aggregator, + ) + + // Try sending again and expect failure since remote is not collateralized + _, err = erc20TokenHome.Send( + optsA, + input, + amount, + ) + Expect(err).Should(Not(BeNil())) + Expect(err.Error()).Should(ContainSubstring(ErrNonZeroCollateralNeeded)) + + // Check the balance of the ERC20TokenHome to ensure it was not changed + balance, err = exampleERC20.BalanceOf(&bind.CallOpts{}, erc20TokenHomeAddress) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(balance, initialBalance) + + // Add collateral to the ERC20TokenHome + utils.AddCollateralToERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + l1AInfo.BlockchainID, + nativeTokenRemoteAddressA, + collateralNeeded, + fundedKey, + ) + + // Check the balance of the ERC20TokenHome to ensure it was increased by the collateral amount. + // Also set the new initial balance before sending tokens + balance, err = exampleERC20.BalanceOf(&bind.CallOpts{}, erc20TokenHomeAddress) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(balance, initialBalance.Add(initialBalance, collateralNeeded)) + + // Send the tokens and expect success now that collateral is added + utils.ERC20DecimalsApprove( + ctx, + exampleERC20, + erc20TokenHomeAddress, + big.NewInt(0).Add(amount, input.PrimaryFee), + cChainInfo, + fundedKey, + ) + tx, err := erc20TokenHome.Send( + optsA, + input, + amount, + ) + Expect(err).Should(BeNil()) + + receipt := utils.WaitForTransactionSuccess(ctx, cChainInfo, tx.Hash()) + event, err := utils.GetEventFromLogs(receipt.Logs, erc20TokenHome.ParseTokensSent) + Expect(err).Should(BeNil()) + Expect(event.Sender).Should(Equal(crypto.PubkeyToAddress(fundedKey.PublicKey))) + + // Compute the scaled amount + scaledAmount := utils.GetScaledAmountFromERC20TokenHome( + erc20TokenHome, + input.DestinationBlockchainID, + input.DestinationTokenTransferrerAddress, + amount, + ) + utils.ExpectBigEqual(event.Amount, scaledAmount) + + // Check the balance of the ERC20TokenHome increased by the transferred amount + balance, err = exampleERC20.BalanceOf(&bind.CallOpts{}, erc20TokenHomeAddress) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(balance, big.NewInt(0).Add(initialBalance, amount)) + + // Relay the message to L1 A and check for a native token mint withdrawal + teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Verify the recipient received the tokens + utils.CheckBalance(ctx, recipientAddress, scaledAmount, l1AInfo.RPCClient) +} diff --git a/icm-contracts/tests/flows/ictt/transparent_proxy_upgradeability.go b/icm-contracts/tests/flows/ictt/transparent_proxy_upgradeability.go new file mode 100644 index 000000000..813b21a60 --- /dev/null +++ b/icm-contracts/tests/flows/ictt/transparent_proxy_upgradeability.go @@ -0,0 +1,234 @@ +package ictt + +import ( + "context" + "math/big" + + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + erc20tokenhomeupgradeable "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHomeUpgradeable" + erc20tokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/** + * Deploy an upgradeable ERC20TokenHome on the primary network + * Deploys a transparent upgradeable proxy that uses the ERC20TokenHome logic contract + * Deploys a proxy admin contract to manage the upgradeable proxy + * Deploy an ERC20TokenRemote to L1 A + * Transfers example erc20 tokens from the primary network to L1 A + * Deploy a new ERC20TokenHome logic contract on the primary network + * Upgrade the transparent upgradeable proxy to use the new logic contract + * Transfer tokens from L1 A back to the primary network + * Check that the transfer was successful, and expected balances are correct + */ + +func TransparentUpgradeableProxy(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy an ExampleERC20 on the primary network as the token to be transferred + exampleERC20Address, exampleERC20 := utils.DeployExampleERC20Decimals( + ctx, + fundedKey, + cChainInfo, + erc20TokenHomeDecimals, + ) + + tokenName, err := exampleERC20.Name(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenSymbol, err := exampleERC20.Symbol(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tokenDecimals, err := exampleERC20.Decimals(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + + opts, err := bind.NewKeyedTransactorWithChainID( + fundedKey, + cChainInfo.EVMChainID, + ) + Expect(err).Should(BeNil()) + implAddress, tx, _, err := erc20tokenhomeupgradeable.DeployERC20TokenHomeUpgradeable( + opts, + cChainInfo.RPCClient, + uint8(1), + ) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(ctx, cChainInfo, tx.Hash()) + + // Deploy a TransparentUpgradeableProxy contract on primary network for the ERC20TokenHome logic contract + erc20TokenHomeAddress, proxyAdmin := utils.DeployTransparentUpgradeableProxy( + ctx, + cChainInfo, + fundedKey, + implAddress, + ) + erc20TokenHome, err := erc20tokenhome.NewERC20TokenHome(erc20TokenHomeAddress, cChainInfo.RPCClient) + Expect(err).Should(BeNil()) + + tx, err = erc20TokenHome.Initialize( + opts, + teleporter.TeleporterRegistryAddress(cChainInfo), + fundedAddress, + big.NewInt(1), + exampleERC20Address, + tokenDecimals, + ) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(ctx, cChainInfo, tx.Hash()) + + // Deploy the ERC20TokenRemote contract on L1 A + erc20TokenRemoteAddress, erc20TokenRemote := utils.DeployERC20TokenRemote( + ctx, + teleporter, + fundedKey, + l1AInfo, + fundedAddress, + cChainInfo.BlockchainID, + erc20TokenHomeAddress, + tokenDecimals, + tokenName, + tokenSymbol, + tokenDecimals, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + utils.RegisterERC20TokenRemoteOnHome( + ctx, + teleporter, + cChainInfo, + erc20TokenHomeAddress, + l1AInfo, + erc20TokenRemoteAddress, + fundedKey, + aggregator, + ) + + // Send a transfer from primary network to L1 A + // Generate new recipient to receive transferred tokens + recipientKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + recipientAddress := crypto.PubkeyToAddress(recipientKey.PublicKey) + + input := erc20tokenhome.SendTokensInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenRemoteAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: exampleERC20Address, + PrimaryFee: big.NewInt(1e18), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(13)) + + receipt, transferredAmount := utils.SendERC20TokenHome( + ctx, + cChainInfo, + erc20TokenHome, + erc20TokenHomeAddress, + exampleERC20, + input, + amount, + fundedKey, + ) + + // Check that the transfer was successful, and expected balances are correct + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + cChainInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + utils.CheckERC20TokenRemoteWithdrawal( + ctx, + erc20TokenRemote, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err := erc20TokenRemote.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) + + // Deploy a new ERC20TokenHome logic contract on primary network + newLogic, tx, _, err := erc20tokenhomeupgradeable.DeployERC20TokenHomeUpgradeable( + opts, + cChainInfo.RPCClient, + uint8(1), + ) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(ctx, cChainInfo, tx.Hash()) + + // Upgrade the TransparentUpgradeableProxy contract to use the new logic contract + tx, err = proxyAdmin.UpgradeAndCall(opts, erc20TokenHomeAddress, newLogic, []byte{}) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(ctx, cChainInfo, tx.Hash()) + + // Send a transfer from L1 A back to primary network + utils.SendNativeTransfer( + ctx, + l1AInfo, + fundedKey, + recipientAddress, + big.NewInt(1e18), + ) + inputB := erc20tokenremote.SendTokensInput{ + DestinationBlockchainID: cChainInfo.BlockchainID, + DestinationTokenTransferrerAddress: erc20TokenHomeAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: erc20TokenRemoteAddress, + PrimaryFee: big.NewInt(1e10), + SecondaryFee: big.NewInt(0), + RequiredGasLimit: utils.DefaultERC20RequiredGas, + } + + receipt, transferredAmount = utils.SendERC20TokenRemote( + ctx, + l1AInfo, + erc20TokenRemote, + erc20TokenRemoteAddress, + inputB, + utils.BigIntSub(transferredAmount, inputB.PrimaryFee), + recipientKey, + ) + + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + cChainInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Check that the transfer was successful, and expected balances are correct + utils.CheckERC20TokenHomeWithdrawal( + ctx, + erc20TokenHomeAddress, + exampleERC20, + receipt, + recipientAddress, + transferredAmount, + ) + + // Check that the recipient received the tokens + balance, err = exampleERC20.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(transferredAmount)) +} diff --git a/icm-contracts/tests/flows/teleporter/add_fee_amount.go b/icm-contracts/tests/flows/teleporter/add_fee_amount.go new file mode 100644 index 000000000..f14abf494 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/add_fee_amount.go @@ -0,0 +1,160 @@ +package teleporter + +import ( + "context" + "math/big" + + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func AddFeeAmount(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + teleporterContractAddress := teleporter.TeleporterMessengerAddress(l1AInfo) + fundedAddress, fundedKey := network.GetFundedAccountInfo() + ctx := context.Background() + + // Use mock token as the fee token + mockTokenAddress, mockToken := utils.DeployExampleERC20( + context.Background(), + fundedKey, + l1AInfo, + ) + utils.ERC20Approve( + ctx, + mockToken, + teleporterContractAddress, + big.NewInt(1e18), + l1AInfo, + fundedKey, + ) + + initFeeAmount := big.NewInt(1) + + // Send a transaction to L1 A that sends a message to L1 B. + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: fundedAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: mockTokenAddress, + Amount: initFeeAmount, + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + sendCrossChainMsgReceipt, messageID := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, + teleporter.TeleporterMessenger(l1AInfo), + l1AInfo, + l1BInfo, + sendCrossChainMessageInput, + fundedKey, + ) + + // Add a fee amount to the message. + additionalFeeAmount := big.NewInt(2) + utils.SendAddFeeAmountAndWaitForAcceptance( + ctx, + l1AInfo, + l1BInfo, + messageID, + additionalFeeAmount, + mockTokenAddress, + fundedKey, + teleporter.TeleporterMessenger(l1AInfo), + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + // Relay message from L1 A to L1 B + deliveryReceipt := teleporter.RelayTeleporterMessage( + ctx, + sendCrossChainMsgReceipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + receiveEvent, err := utils.GetEventFromLogs( + deliveryReceipt.Logs, + teleporter.TeleporterMessenger(l1BInfo).ParseReceiveCrossChainMessage) + Expect(err).Should(BeNil()) + + // Check Teleporter message received on the destination (L1 B) + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived(&bind.CallOpts{}, messageID) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Check the initial relayer reward amount on L1 A. + initialRewardAmount, err := teleporter.TeleporterMessenger(l1AInfo).CheckRelayerRewardAmount( + &bind.CallOpts{}, + receiveEvent.RewardRedeemer, + mockTokenAddress) + Expect(err).Should(BeNil()) + + // Send a message from L1 B back to L1 A that includes the specific receipt for the message. + sendSpecificReceiptsReceipt, sendSpecificReceiptsMessageID := utils.SendSpecifiedReceiptsAndWaitForAcceptance( + ctx, + teleporter.TeleporterMessenger(l1BInfo), + l1BInfo, + l1AInfo.BlockchainID, + [][32]byte{receiveEvent.MessageID}, + teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: mockTokenAddress, + Amount: big.NewInt(0), + }, + []common.Address{}, + fundedKey, + ) + + // Relay message containing the specific receipt from L1 B to L1 A + teleporter.RelayTeleporterMessage( + ctx, + sendSpecificReceiptsReceipt, + l1BInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Check message delivered + delivered, err = teleporter.TeleporterMessenger(l1AInfo).MessageReceived( + &bind.CallOpts{}, + sendSpecificReceiptsMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Check the updated relayer reward amount + expectedIncrease := new(big.Int).Add(initFeeAmount, additionalFeeAmount) + newRewardAmount, err := teleporter.TeleporterMessenger(l1AInfo).CheckRelayerRewardAmount( + &bind.CallOpts{}, + receiveEvent.RewardRedeemer, + mockTokenAddress) + Expect(err).Should(BeNil()) + Expect(newRewardAmount).Should(Equal(new(big.Int).Add(initialRewardAmount, expectedIncrease))) + + // If the funded address is the one able to redeem the rewards, do so and check the reward amount is reset. + if fundedAddress == receiveEvent.RewardRedeemer { + utils.RedeemRelayerRewardsAndConfirm( + ctx, + teleporter.TeleporterMessenger(l1AInfo), + l1AInfo, + mockToken, + mockTokenAddress, + fundedKey, + newRewardAmount, + ) + } +} diff --git a/icm-contracts/tests/flows/teleporter/basic_send_receive.go b/icm-contracts/tests/flows/teleporter/basic_send_receive.go new file mode 100644 index 000000000..f825894db --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/basic_send_receive.go @@ -0,0 +1,138 @@ +package teleporter + +import ( + "context" + "math/big" + + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +// Tests basic one-way send from L1 A to L1 B and vice versa +func BasicSendReceive(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + teleporterContractAddress := teleporter.TeleporterMessengerAddress(l1AInfo) + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // Send a transaction to L1 A to issue an ICM Message from the Teleporter contract to L1 B + ctx := context.Background() + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Clear the receipt queue from L1 B -> L1 A to have a clean slate for the test flow. + // This is only done if the test non-external networks because external networks may have + // an arbitrarily high number of receipts to be cleared from a given queue from unrelated messages. + teleporter.ClearReceiptQueue(ctx, fundedKey, l1BInfo, l1AInfo, aggregator) + + feeAmount := big.NewInt(1) + feeTokenAddress, feeToken := utils.DeployExampleERC20( + ctx, + fundedKey, + l1AInfo, + ) + utils.ERC20Approve( + ctx, + feeToken, + teleporterContractAddress, + big.NewInt(0).Mul(big.NewInt(1e18), + big.NewInt(10)), + l1AInfo, + fundedKey, + ) + + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: fundedAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: feeTokenAddress, + Amount: feeAmount, + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + receipt, teleporterMessageID := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, + teleporter.TeleporterMessenger(l1AInfo), + l1AInfo, + l1BInfo, + sendCrossChainMessageInput, + fundedKey, + ) + expectedReceiptID := teleporterMessageID + + // Relay the message to the destination + deliveryReceipt := teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + receiveEvent, err := utils.GetEventFromLogs( + deliveryReceipt.Logs, + teleporter.TeleporterMessenger(l1BInfo).ParseReceiveCrossChainMessage, + ) + Expect(err).Should(BeNil()) + + // Check Teleporter message received on the destination + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Send a transaction to L1 B to issue an ICM Message from the Teleporter contract to L1 A + sendCrossChainMessageInput.DestinationBlockchainID = l1AInfo.BlockchainID + sendCrossChainMessageInput.FeeInfo.Amount = big.NewInt(0) + receipt, teleporterMessageID = utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, + teleporter.TeleporterMessenger(l1BInfo), + l1BInfo, + l1AInfo, + sendCrossChainMessageInput, + fundedKey, + ) + + // Relay the message to the destination + deliveryReceipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1BInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + Expect(utils.CheckReceiptReceived( + deliveryReceipt, + expectedReceiptID, + teleporter.TeleporterMessenger(l1AInfo))).Should(BeTrue()) + + // Check Teleporter message received on the destination + delivered, err = teleporter.TeleporterMessenger(l1AInfo).MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // If the reward address of the message from A->B is the funded address, which is able to send + // transactions on L1 A, then redeem the rewards. + if receiveEvent.RewardRedeemer == fundedAddress { + utils.RedeemRelayerRewardsAndConfirm( + ctx, teleporter.TeleporterMessenger(l1AInfo), l1AInfo, feeToken, feeTokenAddress, fundedKey, feeAmount, + ) + } +} diff --git a/icm-contracts/tests/flows/teleporter/deliver_to_nonexistent_contract.go b/icm-contracts/tests/flows/teleporter/deliver_to_nonexistent_contract.go new file mode 100644 index 000000000..7b3ea4103 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/deliver_to_nonexistent_contract.go @@ -0,0 +1,172 @@ +package teleporter + +import ( + "context" + "math/big" + + testmessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/tests/TestMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func DeliverToNonExistentContract(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + deployerKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + deployerAddress := crypto.PubkeyToAddress(deployerKey.PublicKey) + + // + // Fund the deployer address on L1 B + // + ctx := context.Background() + log.Info("Funding address on L1 B", "address", deployerAddress.Hex()) + + fundAmount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) // 10eth + fundDeployerTx := utils.CreateNativeTransferTransaction( + ctx, l1BInfo, fundedKey, deployerAddress, fundAmount, + ) + utils.SendTransactionAndWaitForSuccess(ctx, l1BInfo, fundDeployerTx) + + // + // Deploy ExampleMessenger to L1 A, but not to L1 B + // Send a message that should fail to be executed on L1 B + // + log.Info("Deploying ExampleMessenger to L1 A") + _, L1AExampleMessenger := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1AInfo), + l1AInfo, + ) + + // Derive the eventual address of the destination contract on L1 B + nonce, err := l1BInfo.RPCClient.NonceAt(ctx, deployerAddress, nil) + Expect(err).Should(BeNil()) + destinationContractAddress := crypto.CreateAddress(deployerAddress, nonce) + + // + // Call the example messenger contract on L1 A + // + log.Info("Calling ExampleMessenger on L1 A") + optsA, err := bind.NewKeyedTransactorWithChainID( + fundedKey, l1AInfo.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := L1AExampleMessenger.SendMessage( + optsA, + l1BInfo.BlockchainID, + destinationContractAddress, + common.BigToAddress(common.Big0), + big.NewInt(0), + testmessenger.SendMessageRequiredGas, + HELLO_WORLD, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + receipt := utils.WaitForTransactionSuccess(ctx, l1AInfo, tx.Hash()) + + sendEvent, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1AInfo).ParseSendCrossChainMessage, + ) + Expect(err).Should(BeNil()) + Expect(sendEvent.DestinationBlockchainID[:]).Should(Equal(l1BInfo.BlockchainID[:])) + + teleporterMessageID := sendEvent.MessageID + + // + // Relay the message to the destination + // + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + log.Info("Relaying the message to the destination") + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + receiveEvent, err := + utils.GetEventFromLogs(receipt.Logs, teleporter.TeleporterMessenger(l1AInfo).ParseReceiveCrossChainMessage) + Expect(err).Should(BeNil()) + + // + // Check that the message was successfully relayed + // + log.Info("Checking the message was successfully relayed") + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived( + &bind.CallOpts{}, + teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // + // Check that the message was not successfully executed + // + log.Info("Checking the message was not successfully executed") + executionFailedEvent, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1AInfo).ParseMessageExecutionFailed, + ) + Expect(err).Should(BeNil()) + Expect(executionFailedEvent.MessageID).Should(Equal(receiveEvent.MessageID)) + + // + // Deploy the contract on L1 B + // + log.Info("Deploying the contract on L1 B") + exampleMessengerContractB, L1BExampleMessenger := utils.DeployTestMessenger( + ctx, + deployerKey, + deployerAddress, + teleporter.TeleporterRegistryAddress(l1BInfo), + l1BInfo, + ) + + // Confirm that it was deployed at the expected address + Expect(exampleMessengerContractB).Should(Equal(destinationContractAddress)) + + // + // Call retryMessageExecution on L1 B + // + log.Info("Calling retryMessageExecution on L1 B") + receipt = utils.RetryMessageExecutionAndWaitForAcceptance( + ctx, + l1AInfo.BlockchainID, + teleporter.TeleporterMessenger(l1BInfo), + l1BInfo, + receiveEvent.Message, + fundedKey, + ) + log.Info("Checking the message was successfully executed") + messageExecutedEvent, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1AInfo).ParseMessageExecuted, + ) + Expect(err).Should(BeNil()) + Expect(messageExecutedEvent.MessageID).Should(Equal(receiveEvent.MessageID)) + + // + // Verify we received the expected string + // + log.Info("Verifying we received the expected string") + _, currMessage, err := L1BExampleMessenger.GetCurrentMessage(&bind.CallOpts{}, l1AInfo.BlockchainID) + Expect(err).Should(BeNil()) + Expect(currMessage).Should(Equal(HELLO_WORLD)) +} diff --git a/icm-contracts/tests/flows/teleporter/deliver_to_wrong_chain.go b/icm-contracts/tests/flows/teleporter/deliver_to_wrong_chain.go new file mode 100644 index 000000000..db3ea15a8 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/deliver_to_wrong_chain.go @@ -0,0 +1,82 @@ +package teleporter + +import ( + "context" + "math/big" + + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func DeliverToWrongChain(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, L1CInfo := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // + // Get the expected teleporter message ID for L1 C + // + expectedAtoCMessageID, err := teleporter.TeleporterMessenger(l1AInfo).GetNextMessageID( + &bind.CallOpts{}, + L1CInfo.BlockchainID, + ) + Expect(err).Should(BeNil()) + + // + // Submit a message to be sent from L1A to L1B + // + ctx := context.Background() + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, // Message intended for L1B + DestinationAddress: common.HexToAddress("0x1111111111111111111111111111111111111111"), + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: fundedAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + log.Info( + "Sending Teleporter transaction on source chain", + "destinationBlockchainID", l1BInfo.BlockchainID, + ) + + receipt, _ := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, + teleporter.TeleporterMessenger(l1AInfo), + l1AInfo, + l1BInfo, + sendCrossChainMessageInput, + fundedKey, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + L1CInfo, + false, + fundedKey, + nil, + aggregator, + ) + + // + // Check that the message was not received on the L1 C + // + delivered, err := teleporter.TeleporterMessenger(L1CInfo).MessageReceived( + &bind.CallOpts{}, expectedAtoCMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeFalse()) +} diff --git a/icm-contracts/tests/flows/teleporter/insufficient_gas.go b/icm-contracts/tests/flows/teleporter/insufficient_gas.go new file mode 100644 index 000000000..fcf8be79a --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/insufficient_gas.go @@ -0,0 +1,112 @@ +package teleporter + +import ( + "context" + "math/big" + + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func InsufficientGas(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + ctx := context.Background() + + // Deploy TestMessenger to L1s A + _, l1ATestMessenger := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1AInfo), + l1AInfo, + ) + // Deploy TestMessenger to L1s B + testMessengerContractB, l1BTestMessenger := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1BInfo), + l1BInfo, + ) + + // Send message from L1A to L1B with 0 execution gas, which should fail to execute + optsA, err := bind.NewKeyedTransactorWithChainID( + fundedKey, + l1AInfo.EVMChainID, + ) + Expect(err).Should(BeNil()) + tx, err := l1ATestMessenger.SendMessage( + optsA, l1BInfo.BlockchainID, testMessengerContractB, fundedAddress, big.NewInt(0), big.NewInt(0), HELLO_WORLD, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + receipt := utils.WaitForTransactionSuccess(ctx, l1AInfo, tx.Hash()) + + event, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1AInfo).ParseSendCrossChainMessage, + ) + Expect(err).Should(BeNil()) + Expect(event.DestinationBlockchainID[:]).Should(Equal(l1BInfo.BlockchainID[:])) + + messageID := event.MessageID + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Relay message from L1 A to L1 B + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Check Teleporter message received on the destination + delivered, err := + teleporter.TeleporterMessenger(l1BInfo).MessageReceived(&bind.CallOpts{}, messageID) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Check message execution failed event + failedMessageExecutionEvent, err := utils.GetEventFromLogs( + receipt.Logs, teleporter.TeleporterMessenger(l1BInfo).ParseMessageExecutionFailed, + ) + Expect(err).Should(BeNil()) + Expect(failedMessageExecutionEvent.MessageID[:]).Should(Equal(messageID[:])) + Expect(failedMessageExecutionEvent.SourceBlockchainID[:]).Should(Equal(l1AInfo.BlockchainID[:])) + + // Retry message execution. This will execute the message with as much gas as needed + // (up to the transaction gas limit), rather than using the required gas specified in the message itself. + receipt = utils.RetryMessageExecutionAndWaitForAcceptance( + ctx, + l1AInfo.BlockchainID, + teleporter.TeleporterMessenger(l1BInfo), + l1BInfo, + failedMessageExecutionEvent.Message, + fundedKey, + ) + executedEvent, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1BInfo).ParseMessageExecuted, + ) + Expect(err).Should(BeNil()) + Expect(executedEvent.MessageID[:]).Should(Equal(messageID[:])) + Expect(executedEvent.SourceBlockchainID[:]).Should(Equal(l1AInfo.BlockchainID[:])) + + // + // Verify we received the expected string + // + _, currMessage, err := l1BTestMessenger.GetCurrentMessage(&bind.CallOpts{}, l1AInfo.BlockchainID) + Expect(err).Should(BeNil()) + Expect(currMessage).Should(Equal(HELLO_WORLD)) +} diff --git a/icm-contracts/tests/flows/teleporter/registry/check_upgrade_access.go b/icm-contracts/tests/flows/teleporter/registry/check_upgrade_access.go new file mode 100644 index 000000000..62b410ee7 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/registry/check_upgrade_access.go @@ -0,0 +1,108 @@ +package registry + +import ( + "context" + "math/big" + + "github.com/ava-labs/icm-services/icm-contracts/tests/flows" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + + . "github.com/onsi/gomega" +) + +func CheckUpgradeAccess(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1Info := network.GetPrimaryNetworkInfo() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // + // Deploy TestMessenger to the L1 + // + ctx := context.Background() + teleporterAddress := teleporter.TeleporterMessengerAddress(l1Info) + _, testMessenger := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1Info), + l1Info, + ) + + // Check that owner is the funded address + owner, err := testMessenger.Owner(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + Expect(owner).Should(Equal(fundedAddress)) + + // Try to call updateMinTeleporterVersion from a non owner account + nonOwnerKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + nonOwnerAddress := crypto.PubkeyToAddress(nonOwnerKey.PublicKey) + + // Transfer native assets to the non owner account + fundAmount := big.NewInt(0.1e18) // 0.1avax + utils.SendNativeTransfer( + ctx, + l1Info, + fundedKey, + nonOwnerAddress, + fundAmount, + ) + + // Check that access is not granted to the non owner and has no effect + nonOwnerOpts, err := bind.NewKeyedTransactorWithChainID( + nonOwnerKey, l1Info.EVMChainID) + Expect(err).Should(BeNil()) + _, err = testMessenger.PauseTeleporterAddress(nonOwnerOpts, teleporterAddress) + Expect(err).ShouldNot(BeNil()) + Expect(err.Error()).Should(ContainSubstring(flows.ErrTxReverted)) + + // Check that the teleporter address is not paused, because previous call should have failed + isPaused, err := testMessenger.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) + Expect(err).Should(BeNil()) + Expect(isPaused).Should(BeFalse()) + + // Check that the owner is able to pause the Teleporter address + ownerOpts, err := bind.NewKeyedTransactorWithChainID( + fundedKey, l1Info.EVMChainID) + Expect(err).Should(BeNil()) + // Try to call pauseTeleporterAddress from the owner account + tx, err := testMessenger.PauseTeleporterAddress(ownerOpts, teleporterAddress) + Expect(err).Should(BeNil()) + receipt := utils.WaitForTransactionSuccess(ctx, l1Info, tx.Hash()) + pauseTeleporterEvent, err := utils.GetEventFromLogs(receipt.Logs, testMessenger.ParseTeleporterAddressPaused) + Expect(err).Should(BeNil()) + Expect(pauseTeleporterEvent.TeleporterAddress).Should(Equal(teleporterAddress)) + + isPaused, err = testMessenger.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) + Expect(err).Should(BeNil()) + Expect(isPaused).Should(BeTrue()) + + // Transfer ownership to the non owner account + tx, err = testMessenger.TransferOwnership(ownerOpts, nonOwnerAddress) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(ctx, l1Info, tx.Hash()) + + // Try to call unpauseTeleporterAddress from the previous owner account + _, err = testMessenger.UnpauseTeleporterAddress(ownerOpts, teleporterAddress) + Expect(err).ShouldNot(BeNil()) + Expect(err.Error()).Should(ContainSubstring(flows.ErrTxReverted)) + + // Make sure the teleporter address is still paused + isPaused, err = testMessenger.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) + Expect(err).Should(BeNil()) + Expect(isPaused).Should(BeTrue()) + + // Try to call unpauseTeleporterAddress from the non owner account now + tx, err = testMessenger.UnpauseTeleporterAddress(nonOwnerOpts, teleporterAddress) + Expect(err).Should(BeNil()) + receipt = utils.WaitForTransactionSuccess(ctx, l1Info, tx.Hash()) + unpauseTeleporterEvent, err := utils.GetEventFromLogs(receipt.Logs, testMessenger.ParseTeleporterAddressUnpaused) + Expect(err).Should(BeNil()) + Expect(unpauseTeleporterEvent.TeleporterAddress).Should(Equal(teleporterAddress)) + + isPaused, err = testMessenger.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) + Expect(err).Should(BeNil()) + Expect(isPaused).Should(BeFalse()) +} diff --git a/icm-contracts/tests/flows/teleporter/registry/pause_teleporter.go b/icm-contracts/tests/flows/teleporter/registry/pause_teleporter.go new file mode 100644 index 000000000..342ef8e2c --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/registry/pause_teleporter.go @@ -0,0 +1,98 @@ +package registry + +import ( + "context" + + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func PauseTeleporter(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // + // Deploy TestMessenger to L1s A and B + // + ctx := context.Background() + teleporterAddress := teleporter.TeleporterMessengerAddress(l1AInfo) + _, testMessengerA := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1AInfo), + l1AInfo, + ) + testMessengerAddressB, testMessengerB := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1BInfo), + l1BInfo, + ) + + // Pause Teleporter on L1 B + opts, err := bind.NewKeyedTransactorWithChainID( + fundedKey, + l1BInfo.EVMChainID, + ) + Expect(err).Should(BeNil()) + tx, err := testMessengerB.PauseTeleporterAddress(opts, teleporterAddress) + Expect(err).Should(BeNil()) + + receipt := utils.WaitForTransactionSuccess(ctx, l1BInfo, tx.Hash()) + pauseTeleporterEvent, err := utils.GetEventFromLogs(receipt.Logs, testMessengerB.ParseTeleporterAddressPaused) + Expect(err).Should(BeNil()) + Expect(pauseTeleporterEvent.TeleporterAddress).Should(Equal(teleporterAddress)) + + isPaused, err := testMessengerB.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) + Expect(err).Should(BeNil()) + Expect(isPaused).Should(BeTrue()) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Send a message from L1 A to L1 B, which should fail + teleporter.SendExampleCrossChainMessageAndVerify( + ctx, + l1AInfo, + testMessengerA, + l1BInfo, + testMessengerAddressB, + testMessengerB, + fundedKey, + "message_1", + aggregator, + false, + ) + + // Unpause Teleporter on L1 B + tx, err = testMessengerB.UnpauseTeleporterAddress(opts, teleporterAddress) + Expect(err).Should(BeNil()) + + receipt = utils.WaitForTransactionSuccess(ctx, l1BInfo, tx.Hash()) + unpauseTeleporterEvent, err := utils.GetEventFromLogs(receipt.Logs, testMessengerB.ParseTeleporterAddressUnpaused) + Expect(err).Should(BeNil()) + Expect(unpauseTeleporterEvent.TeleporterAddress).Should(Equal(teleporterAddress)) + + isPaused, err = testMessengerB.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) + Expect(err).Should(BeNil()) + Expect(isPaused).Should(BeFalse()) + + // Send a message from L1 A to L1 B again, which should now succeed + teleporter.SendExampleCrossChainMessageAndVerify( + ctx, + l1AInfo, + testMessengerA, + l1BInfo, + testMessengerAddressB, + testMessengerB, + fundedKey, + "message_2", + aggregator, + true, + ) +} diff --git a/icm-contracts/tests/flows/teleporter/registry/teleporter_registry.go b/icm-contracts/tests/flows/teleporter/registry/teleporter_registry.go new file mode 100644 index 000000000..870306c56 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/registry/teleporter_registry.go @@ -0,0 +1,217 @@ +package registry + +import ( + "context" + + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +const ( + teleporterByteCodeFile = "./out/TeleporterMessenger.sol/TeleporterMessenger.json" +) + +func TeleporterRegistry(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + // Deploy dApp on both chains that use Teleporter Registry + // Deploy version 2 of Teleporter to both chains + // Construct AddProtocolVersion txs for both chains + // Send tx for one of the two chains, verify events emitted + // Send a message from chain with old version to chain with new version, verify message is received + // Update minTeleporterVersion on chain with new version + // Send same message from chain with old version, verify message is not received + // Send a message from chain with new version to chain with old version, verify message is not received + // Send tx with new protocol version to other chain, verify events emitted + // Retry the previously failed message execution, verify message is now able to be delivered to dApp + + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, l1BInfo := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // Deploy a test cross chain messenger to both chains + testMessengerContractC, testMessengerC := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(cChainInfo), + cChainInfo, + ) + testMessengerContractB, testMessengerB := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1BInfo), + l1BInfo, + ) + + // Deploy the new version of Teleporter to both chains + var newTeleporterAddress common.Address + for _, l1 := range network.GetAllL1Infos() { + newTeleporterAddress = teleporter.DeployNewTeleporterVersion(ctx, l1, fundedKey, teleporterByteCodeFile) + } + + networkID := network.GetNetworkID() + // Create chain config file with off chain message for each chain + offchainMessageC, warpEnabledChainConfigC := utils.InitOffChainMessageChainConfig( + networkID, + cChainInfo, + teleporter.TeleporterRegistryAddress(cChainInfo), + newTeleporterAddress, + 2, + ) + offchainMessageB, warpEnabledChainConfigB := utils.InitOffChainMessageChainConfig( + networkID, + l1BInfo, + teleporter.TeleporterRegistryAddress(l1BInfo), + newTeleporterAddress, + 2, + ) + offchainMessageA, warpEnabledChainConfigA := utils.InitOffChainMessageChainConfig( + networkID, + l1AInfo, + teleporter.TeleporterRegistryAddress(l1AInfo), + newTeleporterAddress, + 2, + ) + + // Create chain config with off chain messages + chainConfigs := make(utils.ChainConfigMap) + chainConfigs.Add(cChainInfo, warpEnabledChainConfigC) + chainConfigs.Add(l1BInfo, warpEnabledChainConfigB) + chainConfigs.Add(l1AInfo, warpEnabledChainConfigA) + + // Restart nodes with new chain config + network.SetChainConfigs(chainConfigs) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Call addProtocolVersion on L1 B to register the new Teleporter version + teleporter.AddProtocolVersionAndWaitForAcceptance( + ctx, + l1BInfo, + newTeleporterAddress, + fundedKey, + offchainMessageB, + aggregator, + ) + + // Send a message using old Teleporter version to test messenger using new Teleporter version. + // Message should be received successfully since we haven't updated mininum Teleporter version yet. + teleporter.SendExampleCrossChainMessageAndVerify( + ctx, + cChainInfo, + testMessengerC, + l1BInfo, + testMessengerContractB, + testMessengerB, + fundedKey, + "message_1", + aggregator, + true, + ) + + // Update minimum Teleporter version on destination chain + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1BInfo.EVMChainID) + Expect(err).Should(BeNil()) + + latestVersionB, err := teleporter.TeleporterRegistry(l1BInfo).LatestVersion(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + minTeleporterVersion, err := testMessengerB.GetMinTeleporterVersion(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + tx, err := testMessengerB.UpdateMinTeleporterVersion(opts, latestVersionB) + Expect(err).Should(BeNil()) + + receipt := utils.WaitForTransactionSuccess(ctx, l1BInfo, tx.Hash()) + + // Verify that minTeleporterVersion updated + minTeleporterVersionUpdatedEvent, err := utils.GetEventFromLogs( + receipt.Logs, + testMessengerB.ParseMinTeleporterVersionUpdated, + ) + Expect(err).Should(BeNil()) + Expect(minTeleporterVersionUpdatedEvent.OldMinTeleporterVersion.Cmp(minTeleporterVersion)).Should(Equal(0)) + Expect(minTeleporterVersionUpdatedEvent.NewMinTeleporterVersion.Cmp(latestVersionB)).Should(Equal(0)) + + // Send a message using old Teleporter version to test messenger with updated minimum Teleporter version. + // Message should fail since we updated minimum Teleporter version. + teleporter.SendExampleCrossChainMessageAndVerify( + ctx, + cChainInfo, + testMessengerC, + l1BInfo, + testMessengerContractB, + testMessengerB, + fundedKey, + "message_2", + aggregator, + false, + ) + + // Update teleporter with the new TeleporterMessengers + for _, l1 := range network.GetAllL1Infos() { + teleporter.SetTeleporter(newTeleporterAddress, l1) + teleporter.InitializeBlockchainID(l1, fundedKey) + } + + teleporter.SendExampleCrossChainMessageAndVerify( + ctx, + l1BInfo, + testMessengerB, + cChainInfo, + testMessengerContractC, + testMessengerC, + fundedKey, + "message_3", + aggregator, + false, + ) + + // Call addProtocolVersion on L1A to register the new Teleporter version + teleporter.AddProtocolVersionAndWaitForAcceptance( + ctx, + cChainInfo, + newTeleporterAddress, + fundedKey, + offchainMessageC, + aggregator, + ) + + // Send a message from A->B, which previously failed, but now using the new Teleporter version. + // Teleporter versions should match, so message should be received successfully. + teleporter.SendExampleCrossChainMessageAndVerify( + ctx, + l1BInfo, + testMessengerB, + cChainInfo, + testMessengerContractC, + testMessengerC, + fundedKey, + "message_4", + aggregator, + true, + ) + + // To make sure all L1s are using the same Teleporter version, call addProtocolVersion on L1A + // to register the new Teleporter version + teleporter.AddProtocolVersionAndWaitForAcceptance( + ctx, + l1AInfo, + newTeleporterAddress, + fundedKey, + offchainMessageA, + aggregator, + ) + + latestVersionA, err := teleporter.TeleporterRegistry(l1AInfo).LatestVersion(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + Expect(latestVersionA.Cmp(latestVersionB)).Should(Equal(0)) + + latestVersionC, err := teleporter.TeleporterRegistry(cChainInfo).LatestVersion(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + Expect(latestVersionC.Cmp(latestVersionB)).Should(Equal(0)) +} diff --git a/icm-contracts/tests/flows/teleporter/relay_message_twice.go b/icm-contracts/tests/flows/teleporter/relay_message_twice.go new file mode 100644 index 000000000..51be71f1e --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/relay_message_twice.go @@ -0,0 +1,93 @@ +package teleporter + +import ( + "context" + "math/big" + + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + + . "github.com/onsi/gomega" +) + +func RelayMessageTwice(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // + // Send a transaction to L1 A to issue an ICM Message from the Teleporter contract to L1 B + // + ctx := context.Background() + + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: fundedAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: fundedAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + log.Info( + "Sending Teleporter transaction on source chain", + "destinationBlockchainID", l1BInfo.BlockchainID, + ) + receipt, teleporterMessageID := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, + teleporter.TeleporterMessenger(l1AInfo), + l1AInfo, + l1BInfo, + sendCrossChainMessageInput, + fundedKey, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // + // Relay the message to the destination + // + teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // + // Check Teleporter message received on the destination + // + log.Info("Checking the message was received on the destination") + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // + // Attempt to send the same message again, should fail + // + log.Info("Relaying the same Teleporter message again on the destination") + teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + false, + fundedKey, + nil, + aggregator, + ) +} diff --git a/icm-contracts/tests/flows/teleporter/relayer_modifies_message.go b/icm-contracts/tests/flows/teleporter/relayer_modifies_message.go new file mode 100644 index 000000000..3f63f97c4 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/relayer_modifies_message.go @@ -0,0 +1,185 @@ +package teleporter + +import ( + "context" + "crypto/ecdsa" + "math/big" + + "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/evm/predicate" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + gasUtils "github.com/ava-labs/icm-services/icm-contracts/utils/gas-utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + . "github.com/onsi/gomega" +) + +// Disallow this test from being run on anything but a local network, since it requires special behavior by the relayer +func RelayerModifiesMessage(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // Send a transaction to L1 A to issue a Warp Message from the Teleporter contract to L1 B + ctx := context.Background() + + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: fundedAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: fundedAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + receipt, messageID := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, teleporter.TeleporterMessenger(l1AInfo), l1AInfo, l1BInfo, sendCrossChainMessageInput, fundedKey) + + // Relay the message to the destination + // Relayer modifies the message in flight + relayAlteredMessage( + ctx, + teleporter, + receipt, + l1AInfo, + l1BInfo, + network, + ) + + // Check Teleporter message was not received on the destination + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived(&bind.CallOpts{}, messageID) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeFalse()) +} + +func relayAlteredMessage( + ctx context.Context, + teleporter utils.TeleporterTestInfo, + sourceReceipt *types.Receipt, + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + network *localnetwork.LocalNetwork, +) { + // Fetch the Teleporter message from the logs + sendEvent, err := utils.GetEventFromLogs( + sourceReceipt.Logs, + teleporter.TeleporterMessenger(source).ParseSendCrossChainMessage, + ) + Expect(err).Should(BeNil()) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + signedWarpMessage := utils.ConstructSignedWarpMessage( + ctx, + sourceReceipt, + source, + destination, + nil, + aggregator, + ) + + // Construct the transaction to send the Warp message to the destination chain + _, fundedKey := network.GetFundedAccountInfo() + signedTx := createAlteredReceiveCrossChainMessageTransaction( + ctx, + signedWarpMessage, + &sendEvent.Message, + sendEvent.Message.RequiredGasLimit, + teleporter.TeleporterMessengerAddress(source), + fundedKey, + destination, + ) + + log.Info("Sending transaction to destination chain") + utils.SendTransactionAndWaitForFailure(ctx, destination, signedTx) +} + +func createAlteredReceiveCrossChainMessageTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + teleporterMessage *teleportermessenger.TeleporterMessage, + requiredGasLimit *big.Int, + teleporterContractAddress common.Address, + fundedKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, +) *types.Transaction { + fundedAddress := crypto.PubkeyToAddress(fundedKey.PublicKey) + // Construct the transaction to send the Warp message to the destination chain + log.Info("Constructing transaction for the destination chain") + + numSigners, err := signedMessage.Signature.NumSigners() + Expect(err).Should(BeNil()) + + upgradeRules := upgrade.GetConfig(constants.MainnetID) + gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit( + &gasUtils.UpgradeRules{UpgradeConfig: upgradeRules}, + numSigners, + requiredGasLimit, + len(predicate.New(signedMessage.Bytes())), + len(signedMessage.Payload), + len(teleporterMessage.Receipts), + ) + Expect(err).Should(BeNil()) + + callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, fundedAddress) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := utils.CalculateTxParams(ctx, l1Info, fundedAddress) + + alterTeleporterMessage(signedMessage) + + destinationTx := types.NewTx(&types.DynamicFeeTx{ + ChainID: l1Info.EVMChainID, + Nonce: nonce, + To: &teleporterContractAddress, + Gas: gasLimit, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: common.Big0, + Data: callData, + AccessList: types.AccessList{ + { + Address: warp.ContractAddress, + StorageKeys: predicate.New(signedMessage.Bytes()), + }, + }, + }) + + return utils.SignTransaction(destinationTx, fundedKey, l1Info.EVMChainID) +} + +func alterTeleporterMessage(signedMessage *avalancheWarp.Message) { + warpMsgPayload, err := warpPayload.ParseAddressedCall(signedMessage.UnsignedMessage.Payload) + Expect(err).Should(BeNil()) + + teleporterMessage := teleportermessenger.TeleporterMessage{} + err = teleporterMessage.Unpack(warpMsgPayload.Payload) + Expect(err).Should(BeNil()) + // Alter the message + teleporterMessage.Message[0] = ^teleporterMessage.Message[0] + + // Pack the teleporter message + teleporterMessageBytes, err := teleporterMessage.Pack() + Expect(err).Should(BeNil()) + + payload, err := warpPayload.NewAddressedCall(warpMsgPayload.SourceAddress, teleporterMessageBytes) + Expect(err).Should(BeNil()) + + signedMessage.UnsignedMessage.Payload = payload.Bytes() + + signedMessage.Initialize() +} diff --git a/icm-contracts/tests/flows/teleporter/resubmit_altered_message.go b/icm-contracts/tests/flows/teleporter/resubmit_altered_message.go new file mode 100644 index 000000000..27a213219 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/resubmit_altered_message.go @@ -0,0 +1,85 @@ +package teleporter + +import ( + "context" + "math/big" + + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func ResubmitAlteredMessage(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // Send a transaction to L1 A to issue an ICM Message from the Teleporter contract to L1 B + ctx := context.Background() + + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: fundedAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: fundedAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + receipt, messageID := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, teleporter.TeleporterMessenger(l1AInfo), l1AInfo, l1BInfo, sendCrossChainMessageInput, fundedKey) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Relay the message to the destination + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + + log.Info("Checking the message was received on the destination") + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived(&bind.CallOpts{}, messageID) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Get the Teleporter message from receive event + event, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1BInfo).ParseReceiveCrossChainMessage, + ) + Expect(err).Should(BeNil()) + Expect(event.MessageID[:]).Should(Equal(messageID[:])) + teleporterMessage := event.Message + + // Alter the message + alteredMessage := make([]byte, len(teleporterMessage.Message)) + copy(alteredMessage, teleporterMessage.Message) + alteredMessage[0] = ^alteredMessage[0] + Expect(alteredMessage[:]).ShouldNot(Equal(teleporterMessage.Message[:])) + teleporterMessage.Message = alteredMessage + + // Resubmit the altered message + log.Info("Submitting the altered Teleporter message on the source chain") + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1AInfo.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := teleporter.TeleporterMessenger(l1AInfo).RetrySendCrossChainMessage(opts, teleporterMessage) + Expect(err).ShouldNot(BeNil()) + + // We expect the tx to be nil because the ICM message failed verification, which happens in the predicate + // In that case, the block is never built, and the transaction is never mined + Expect(tx).Should(BeNil()) +} diff --git a/icm-contracts/tests/flows/teleporter/retry_successful_execution.go b/icm-contracts/tests/flows/teleporter/retry_successful_execution.go new file mode 100644 index 000000000..9568e39ec --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/retry_successful_execution.go @@ -0,0 +1,119 @@ +package teleporter + +import ( + "context" + "math/big" + + testmessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/tests/TestMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +const HELLO_WORLD = "Hello, world!" + +func RetrySuccessfulExecution(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // + // Deploy TestMessenger to L1s A and B + // + ctx := context.Background() + + _, l1ATestMessenger := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1AInfo), + l1AInfo, + ) + testMessengerContractAddressB, l1BTestMessenger := utils.DeployTestMessenger( + ctx, + fundedKey, + fundedAddress, + teleporter.TeleporterRegistryAddress(l1BInfo), + l1BInfo, + ) + + // + // Call the test messenger contract on L1 A + // + optsA, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1AInfo.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := l1ATestMessenger.SendMessage( + optsA, + l1BInfo.BlockchainID, + testMessengerContractAddressB, + fundedAddress, + big.NewInt(0), + testmessenger.SendMessageRequiredGas, + HELLO_WORLD, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + receipt := utils.WaitForTransactionSuccess(ctx, l1AInfo, tx.Hash()) + + event, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1AInfo).ParseSendCrossChainMessage, + ) + Expect(err).Should(BeNil()) + Expect(event.DestinationBlockchainID[:]).Should(Equal(l1BInfo.BlockchainID[:])) + + teleporterMessageID := event.MessageID + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // + // Relay the message to the destination + // + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + receiveEvent, err := + utils.GetEventFromLogs(receipt.Logs, teleporter.TeleporterMessenger(l1BInfo).ParseReceiveCrossChainMessage) + Expect(err).Should(BeNil()) + deliveredTeleporterMessage := receiveEvent.Message + + // + // Check Teleporter message received on the destination + // + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // + // Verify we received the expected string + // + _, currMessage, err := l1BTestMessenger.GetCurrentMessage(&bind.CallOpts{}, l1AInfo.BlockchainID) + Expect(err).Should(BeNil()) + Expect(currMessage).Should(Equal(HELLO_WORLD)) + + // + // Attempt to retry message execution, which should fail + // + optsB, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1BInfo.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err = teleporter.TeleporterMessenger(l1BInfo).RetryMessageExecution( + optsB, + l1AInfo.BlockchainID, + deliveredTeleporterMessage, + ) + Expect(err).Should(Not(BeNil())) + Expect(tx).Should(BeNil()) +} diff --git a/icm-contracts/tests/flows/teleporter/send_specific_receipts.go b/icm-contracts/tests/flows/teleporter/send_specific_receipts.go new file mode 100644 index 000000000..e0c752a92 --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/send_specific_receipts.go @@ -0,0 +1,307 @@ +package teleporter + +import ( + "bytes" + "context" + goLog "log" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + teleporterutils "github.com/ava-labs/icm-services/icm-contracts/utils/teleporter-utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func SendSpecificReceipts(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + l1ATeleporterMessenger := teleporter.TeleporterMessenger(l1AInfo) + l1BTeleporterMessenger := teleporter.TeleporterMessenger(l1BInfo) + teleporterContractAddress := teleporter.TeleporterMessengerAddress(l1AInfo) + _, fundedKey := network.GetFundedAccountInfo() + ctx := context.Background() + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Clear the receipt queue from L1 B -> L1 A to have a clean slate for the test flow. + teleporter.ClearReceiptQueue(ctx, fundedKey, l1BInfo, l1AInfo, aggregator) + + // Use mock token as the fee token + mockTokenAddress, mockToken := utils.DeployExampleERC20( + ctx, fundedKey, l1AInfo, + ) + utils.ERC20Approve( + ctx, + mockToken, + teleporterContractAddress, + big.NewInt(0).Mul(big.NewInt(1e18), + big.NewInt(10)), + l1AInfo, + fundedKey, + ) + + // Send two messages from L1 A to L1 B + relayerFeePerMessage := big.NewInt(5) + destinationAddress := common.HexToAddress("0x1111111111111111111111111111111111111111") + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: destinationAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: mockTokenAddress, + Amount: relayerFeePerMessage, + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + goLog.Println("Sending two messages from L1 A to L1 B") + + // Send first message from L1 A to L1 B with fee amount 5 + sendCrossChainMsgReceipt, messageID1 := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, l1ATeleporterMessenger, l1AInfo, l1BInfo, sendCrossChainMessageInput, fundedKey) + + goLog.Println("Relaying the first message from L1 A to L1 B") + // Relay the message from L1A to L1B + deliveryReceipt1 := teleporter.RelayTeleporterMessage( + ctx, + sendCrossChainMsgReceipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + receiveEvent1, err := utils.GetEventFromLogs( + deliveryReceipt1.Logs, + l1BTeleporterMessenger.ParseReceiveCrossChainMessage, + ) + Expect(err).Should(BeNil()) + Expect(receiveEvent1.MessageID[:]).Should(Equal(messageID1[:])) + + // Check that the first message was delivered + delivered, err := l1BTeleporterMessenger.MessageReceived(&bind.CallOpts{}, messageID1) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + goLog.Println("Sending the second message from L1 A to L1 B") + // Send second message from L1 A to L1 B with fee amount 5 + sendCrossChainMsgReceipt, messageID2 := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, l1ATeleporterMessenger, l1AInfo, l1BInfo, sendCrossChainMessageInput, fundedKey) + + goLog.Println("Relaying the second message from L1 A to L1 B") + // Relay the message from L1 A to L1 B + deliveryReceipt2 := teleporter.RelayTeleporterMessage( + ctx, + sendCrossChainMsgReceipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + receiveEvent2, err := utils.GetEventFromLogs( + deliveryReceipt2.Logs, + l1BTeleporterMessenger.ParseReceiveCrossChainMessage) + Expect(err).Should(BeNil()) + Expect(receiveEvent2.MessageID[:]).Should(Equal(messageID2[:])) + + // Check that the second message was delivered + delivered, err = l1BTeleporterMessenger.MessageReceived(&bind.CallOpts{}, messageID2) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Call send specific receipts to get reward of relaying two messages + goLog.Println("Sending specific receipts from L1 B to L1 A") + receipt, messageID := utils.SendSpecifiedReceiptsAndWaitForAcceptance( + ctx, + l1BTeleporterMessenger, + l1BInfo, + l1AInfo.BlockchainID, + [][32]byte{messageID1, messageID2}, + teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: mockTokenAddress, + Amount: big.NewInt(0), + }, + []common.Address{}, + fundedKey, + ) + + // Relay message from L1 B to L1 A + goLog.Println("Relaying the specific receipts from L1 B to L1 A") + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1BInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Check that the message back to L1 A was delivered + delivered, err = l1ATeleporterMessenger.MessageReceived(&bind.CallOpts{}, messageID) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Check that the expected receipts were received and emitted ReceiptReceived + Expect(utils.CheckReceiptReceived(receipt, messageID1, l1ATeleporterMessenger)).Should(BeTrue()) + Expect(utils.CheckReceiptReceived(receipt, messageID2, l1ATeleporterMessenger)).Should(BeTrue()) + + // Check the reward amounts. + // Even on external networks, the relayer should only have the expected fee amount + // for this asset because the asset contract was newly deployed by this test. + checkExpectedRewardAmounts( + teleporter, + l1AInfo, + receiveEvent1, + receiveEvent2, + mockTokenAddress, + relayerFeePerMessage, + ) + + // Send a message from L1 B to L1 A to trigger + // the "regular" method of delivering receipts. The next message from B->A will contain the same receipts + // that were manually sent in the above steps, but they should not be processed again on L1 A. + sendCrossChainMessageInput = teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1AInfo.BlockchainID, + DestinationAddress: destinationAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: mockTokenAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + goLog.Println("Sending a message from L1 B to L1 A to trigger receipts") + // This message will also have the same receipts as the previous message + receipt, messageID = utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, l1BTeleporterMessenger, l1BInfo, l1AInfo, sendCrossChainMessageInput, fundedKey) + + goLog.Println("Relaying the message from L1 B to L1 A") + // Relay message from L1 B to L1 A + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1BInfo, + l1AInfo, + true, + fundedKey, + nil, + aggregator, + ) + // Check delivered + delivered, err = l1ATeleporterMessenger.MessageReceived( + &bind.CallOpts{}, + messageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // Check that the expected receipts were included in the message but did not emit ReceiptReceived + // because they were previously received + Expect(utils.CheckReceiptReceived(receipt, messageID1, l1ATeleporterMessenger)).Should(BeFalse()) + Expect(utils.CheckReceiptReceived(receipt, messageID2, l1ATeleporterMessenger)).Should(BeFalse()) + + receiveEvent, err := utils.GetEventFromLogs( + receipt.Logs, + l1ATeleporterMessenger.ParseReceiveCrossChainMessage, + ) + Expect(err).Should(BeNil()) + log.Info("Receipt included", "count", len(receiveEvent.Message.Receipts), "receipts", receiveEvent.Message.Receipts) + Expect(receiptIncluded( + teleporterContractAddress, + messageID1, + l1AInfo, + l1BInfo, + receiveEvent.Message.Receipts)).Should(BeTrue()) + Expect(receiptIncluded( + teleporterContractAddress, + messageID2, + l1AInfo, + l1BInfo, + receiveEvent.Message.Receipts)).Should(BeTrue()) + + // Check the reward amount remains the same + checkExpectedRewardAmounts( + teleporter, + l1AInfo, + receiveEvent1, + receiveEvent2, + mockTokenAddress, + relayerFeePerMessage, + ) +} + +// Checks the given message ID is included in the list of receipts. +func receiptIncluded( + teleporterMessengerAddress common.Address, + expectedMessageID ids.ID, + sourceL1 interfaces.L1TestInfo, + destinationL1 interfaces.L1TestInfo, + receipts []teleportermessenger.TeleporterMessageReceipt, +) bool { + for _, receipt := range receipts { + messageID, err := teleporterutils.CalculateMessageID( + teleporterMessengerAddress, + sourceL1.BlockchainID, + destinationL1.BlockchainID, + receipt.ReceivedMessageNonce, + ) + Expect(err).Should(BeNil()) + if bytes.Equal(messageID[:], expectedMessageID[:]) { + return true + } + } + return false +} + +// Checks that the reward redeemers specified by the two provided message receipts +// are able to redeem the correct amount of the rewards of the given token. It is +// assumed that the {tokenAddress} was used as the fee asset for each of the messages, +// and that each message individually had a fee of {feePerMessage}. +func checkExpectedRewardAmounts( + teleporter utils.TeleporterTestInfo, + sourceL1 interfaces.L1TestInfo, + receiveEvent1 *teleportermessenger.TeleporterMessengerReceiveCrossChainMessage, + receiveEvent2 *teleportermessenger.TeleporterMessengerReceiveCrossChainMessage, + tokenAddress common.Address, + feePerMessage *big.Int, +) { + // Check the reward amounts. + // If the same address is the reward redeemer for both messages, + // it should be able to redeem {feePerMessage}*2. Otherwise, + // each distinct reward redeemer should be able to redeem {feePerMessage}. + if receiveEvent1.RewardRedeemer == receiveEvent2.RewardRedeemer { + amount, err := teleporter[sourceL1.BlockchainID].TeleporterMessenger.CheckRelayerRewardAmount( + &bind.CallOpts{}, + receiveEvent1.RewardRedeemer, + tokenAddress) + Expect(err).Should(BeNil()) + Expect(amount).Should(Equal(new(big.Int).Mul(feePerMessage, big.NewInt(2)))) + } else { + amount1, err := teleporter[sourceL1.BlockchainID].TeleporterMessenger.CheckRelayerRewardAmount( + &bind.CallOpts{}, + receiveEvent1.RewardRedeemer, + tokenAddress) + Expect(err).Should(BeNil()) + Expect(amount1).Should(Equal(feePerMessage)) + amount2, err := teleporter[sourceL1.BlockchainID].TeleporterMessenger.CheckRelayerRewardAmount( + &bind.CallOpts{}, + receiveEvent2.RewardRedeemer, + tokenAddress) + Expect(err).Should(BeNil()) + Expect(amount2).Should(Equal(feePerMessage)) + } +} diff --git a/icm-contracts/tests/flows/teleporter/teleporter_message_ids.go b/icm-contracts/tests/flows/teleporter/teleporter_message_ids.go new file mode 100644 index 000000000..27efc1fed --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/teleporter_message_ids.go @@ -0,0 +1,43 @@ +// // (c) 2024, Ava Labs, Inc. All rights reserved. +// // See the file LICENSE for licensing terms. + +package teleporter + +import ( + "math/big" + + "github.com/ava-labs/avalanchego/ids" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + teleporterutils "github.com/ava-labs/icm-services/icm-contracts/utils/teleporter-utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +// Tests Teleporter message ID calculation +func CalculateMessageID(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1Info := network.GetPrimaryNetworkInfo() + teleporterContractAddress := teleporter.TeleporterMessengerAddress(l1Info) + + sourceBlockchainID := common.HexToHash("0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd") + destinationBlockchainID := common.HexToHash("0x1234567812345678123456781234567812345678123456781234567812345678") + nonce := big.NewInt(42) + + expectedMessageID, err := teleporter.TeleporterMessenger(l1Info).CalculateMessageID( + &bind.CallOpts{}, + sourceBlockchainID, + destinationBlockchainID, + nonce, + ) + Expect(err).Should(BeNil()) + + calculatedMessageID, err := teleporterutils.CalculateMessageID( + teleporterContractAddress, + ids.ID(sourceBlockchainID), + ids.ID(destinationBlockchainID), + nonce, + ) + Expect(err).Should(BeNil()) + Expect(ids.ID(expectedMessageID)).Should(Equal(calculatedMessageID)) +} diff --git a/icm-contracts/tests/flows/teleporter/unallowed_relayer.go b/icm-contracts/tests/flows/teleporter/unallowed_relayer.go new file mode 100644 index 000000000..e182ff9eb --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/unallowed_relayer.go @@ -0,0 +1,74 @@ +package teleporter + +import ( + "context" + "math/big" + + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func UnallowedRelayer(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo := network.GetPrimaryNetworkInfo() + l1BInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + // + // Send a transaction to L1 A to issue an ICM Message from the Teleporter contract to L1 B + // The Teleporter message includes an allowed relayer list that does NOT include the relayer + // + ctx := context.Background() + + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: fundedAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: fundedAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{ + common.HexToAddress("0x0123456789012345678901234567890123456789"), + }, + Message: []byte{1, 2, 3, 4}, + } + + log.Info( + "Sending Teleporter transaction on source chain", + "destinationBlockchainID", l1BInfo.BlockchainID, + ) + receipt, teleporterMessageID := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, teleporter.TeleporterMessenger(l1AInfo), l1AInfo, l1BInfo, sendCrossChainMessageInput, fundedKey, + ) + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // + // Relay the message to the destination + // + teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + false, + fundedKey, + nil, + aggregator, + ) + + // + // Check Teleporter message was not received on the destination + // + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeFalse()) +} diff --git a/icm-contracts/tests/flows/teleporter/validator_churn.go b/icm-contracts/tests/flows/teleporter/validator_churn.go new file mode 100644 index 000000000..c2255e3ea --- /dev/null +++ b/icm-contracts/tests/flows/teleporter/validator_churn.go @@ -0,0 +1,189 @@ +package teleporter + +import ( + "context" + "math/big" + "time" + + "github.com/ava-labs/avalanchego/utils/units" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + poamanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/PoAManager" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +const ( + newNodeCount = 2 + sleepPeriodSeconds = 5 +) + +func ValidatorChurn(network *localnetwork.LocalNetwork, teleporter utils.TeleporterTestInfo) { + l1AInfo, l1BInfo := network.GetTwoL1s() + teleporterContractAddress := teleporter.TeleporterMessengerAddress(l1AInfo) + fundedAddress, fundedKey := network.GetFundedAccountInfo() + + ctx := context.Background() + + // + // Send a Teleporter message on L1 A + // + log.Info("Sending Teleporter message on source chain", "destinationBlockchainID", l1BInfo.BlockchainID) + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: l1BInfo.BlockchainID, + DestinationAddress: fundedAddress, + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: fundedAddress, + Amount: big.NewInt(0), + }, + RequiredGasLimit: big.NewInt(1), + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + receipt, teleporterMessageID := utils.SendCrossChainMessageAndWaitForAcceptance( + ctx, + teleporter.TeleporterMessenger(l1AInfo), + l1AInfo, + l1BInfo, + sendCrossChainMessageInput, + fundedKey, + ) + + sendEvent, err := utils.GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(l1AInfo).ParseSendCrossChainMessage, + ) + Expect(err).Should(BeNil()) + sentTeleporterMessage := sendEvent.Message + + aggregator := network.GetSignatureAggregator() + defer aggregator.Shutdown() + + // Construct the signed warp message + signedWarpMessage := utils.ConstructSignedWarpMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + nil, + aggregator, + ) + + // + // Modify the validator set on L1 A + // + + // Add new nodes to the validator set + addValidatorsCtx, cancel := context.WithTimeout(ctx, (90+sleepPeriodSeconds)*newNodeCount*time.Second) + defer cancel() + newNodes := network.GetExtraNodes(newNodeCount) + validatorManagerProxy, poaManagerProxy := network.GetValidatorManager(l1AInfo.SubnetID) + poaManager, err := poamanager.NewPoAManager(poaManagerProxy.Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + pChainInfo := utils.GetPChainInfo(network.GetPrimaryNetworkInfo()) + Expect(err).Should(BeNil()) + + l1AInfo = network.AddSubnetValidators(newNodes, l1AInfo, true) + + for i := 0; i < newNodeCount; i++ { + expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) + pop, err := newNodes[i].GetProofOfPossession() + Expect(err).Should(BeNil()) + node := utils.Node{ + NodeID: newNodes[i].NodeID, + NodePoP: pop, + Weight: units.Schmeckle, + } + utils.InitiateAndCompletePoAValidatorRegistration( + addValidatorsCtx, + aggregator, + fundedKey, + l1AInfo, + pChainInfo, + poaManager, + poaManagerProxy.Address, + validatorManagerProxy.Address, + expiry, + node, + network.GetPChainWallet(), + network.GetNetworkID(), + ) + // Sleep to ensure the validator manager uses a new churn tracking period + time.Sleep(sleepPeriodSeconds * time.Second) + } + + // Refresh the L1 info + l1AInfo, l1BInfo = network.GetTwoL1s() + + // Trigger the proposer VM to update its height so that the inner VM can see the new validator set + // We have to update all L1s, not just the ones directly involved in this test to ensure that the + // proposer VM is updated on all L1s. + for _, l1Info := range network.GetL1Infos() { + err = utils.IssueTxsToAdvanceChain( + ctx, l1Info.EVMChainID, fundedKey, l1Info.WSClient, 5, + ) + Expect(err).Should(BeNil()) + } + + // + // Attempt to deliver the warp message signed by the old validator set. This should fail. + // + // Construct the transaction to send the Warp message to the destination chain + signedTx := utils.CreateReceiveCrossChainMessageTransaction( + ctx, + signedWarpMessage, + teleporterContractAddress, + fundedKey, + l1BInfo, + ) + + log.Info("Sending transaction to destination chain") + utils.SendTransactionAndWaitForFailure(ctx, l1BInfo, signedTx) + + // Verify the message was not delivered + delivered, err := teleporter.TeleporterMessenger(l1BInfo).MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeFalse()) + + // + // Retry sending the message, and attempt to relay again. This should succeed. + // + log.Info("Retrying message sending on source chain") + optsA, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1AInfo.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := teleporter.TeleporterMessenger(l1AInfo).RetrySendCrossChainMessage( + optsA, sentTeleporterMessage, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + receipt = utils.WaitForTransactionSuccess(ctx, l1AInfo, tx.Hash()) + + teleporter.RelayTeleporterMessage( + ctx, + receipt, + l1AInfo, + l1BInfo, + true, + fundedKey, + nil, + aggregator, + ) + + // Verify the message was delivered + delivered, err = teleporter.TeleporterMessenger(l1BInfo).MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + // The test cases now do not require any specific nodes to be validators, so leave the validator set as is. + // If this changes in the future, this test will need to perform cleanup by removing the nodes that were added + // and re-adding the nodes that were removed. +} diff --git a/icm-contracts/tests/flows/validator-manager/delegator_inactive_validator.go b/icm-contracts/tests/flows/validator-manager/delegator_inactive_validator.go new file mode 100644 index 000000000..62e109ab1 --- /dev/null +++ b/icm-contracts/tests/flows/validator-manager/delegator_inactive_validator.go @@ -0,0 +1,282 @@ +package staking + +import ( + "context" + "log" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/units" + exampleerc20 "github.com/ava-labs/icm-services/abi-bindings/go/mocks/ExampleERC20" + erc20tokenstakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ERC20TokenStakingManager" + istakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/interfaces/IStakingManager" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/* + * Tests that a delegator can recover its funds from an inactive validator. + * The steps are as follows: + * - Deploy an ERC20TokenStakingManager + * - Initiate and complete validator registration + * - Initiate and complete delegator registration + * - Disable the validator by issuing a DisableL1ValidatorTx on the P-Chain + * - Initiate and complete validator removal + */ +func RemoveDelegatorInactiveValidator(network *localnetwork.LocalNetwork) { + // Get the L1s info + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + fundedAddress, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + ctx := context.Background() + + balance := 100 * units.Avax + nodes, initialValidationIDs := network.ConvertSubnet( + ctx, + l1AInfo, + utils.ERC20TokenStakingManager, + []uint64{units.Schmeckle, 1000 * units.Schmeckle}, // Choose weights to avoid validator churn limits + []uint64{balance, balance}, + fundedKey, + false, + ) + validatorManagerProxy, stakingManagerProxy := network.GetValidatorManager(l1AInfo.SubnetID) + erc20StakingManager, err := erc20tokenstakingmanager.NewERC20TokenStakingManager( + stakingManagerProxy.Address, + l1AInfo.RPCClient, + ) + Expect(err).Should(BeNil()) + erc20Address, err := erc20StakingManager.Erc20(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + erc20, err := exampleerc20.NewExampleERC20(erc20Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + l1AInfo.SubnetID, + }, + ) + defer signatureAggregator.Shutdown() + + // + // Delist one initial validator + // + posStakingManager, err := istakingmanager.NewIStakingManager(stakingManagerProxy.Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + utils.InitiateAndCompleteEndInitialPoSValidation( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + posStakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + initialValidationIDs[0], + 0, + nodes[0].Weight, + network.GetPChainWallet(), + network.GetNetworkID(), + ) + + // + // Register the validator as PoS + // + registrationInitiatedEvent := utils.InitiateAndCompleteERC20ValidatorRegistration( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + erc20StakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + erc20, + nodes[0], + network.GetPChainWallet(), + network.GetNetworkID(), + ) + validationID := ids.ID(registrationInitiatedEvent.ValidationID) + + // + // Register a delegator + // + var delegationID ids.ID + delegatorStake, err := erc20StakingManager.WeightToValue( + &bind.CallOpts{}, + nodes[0].Weight, + ) + Expect(err).Should(BeNil()) + delegatorStake.Div(delegatorStake, big.NewInt(10)) + delegatorWeight, err := erc20StakingManager.ValueToWeight( + &bind.CallOpts{}, + delegatorStake, + ) + Expect(err).Should(BeNil()) + + // Get the delegator's staking token balance + delegatorBalance, err := erc20.BalanceOf(&bind.CallOpts{}, fundedAddress) + Expect(err).Should(BeNil()) + { + log.Println("Registering delegator") + newValidatorWeight := nodes[0].Weight + delegatorWeight + + nonce := uint64(1) + + receipt := utils.InitiateERC20DelegatorRegistration( + ctx, + fundedKey, + l1AInfo, + validationID, + delegatorStake, + erc20, + stakingManagerProxy.Address, + erc20StakingManager, + ) + initRegistrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseInitiatedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + delegationID = initRegistrationEvent.DelegationID + + // Gather subnet-evm Warp signatures for the L1ValidatorWeightMessage & relay to the P-Chain + signedWarpMessage := utils.ConstructSignedWarpMessage( + context.Background(), + receipt, + l1AInfo, + pChainInfo, + nil, + signatureAggregator, + ) + + // Issue a tx to update the validator's weight on the P-Chain + _, err = network.GetPChainWallet().IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + Expect(err).Should(BeNil()) + utils.PChainProposerVMWorkaround(network.GetPChainWallet()) + utils.AdvanceProposerVM(ctx, l1AInfo, fundedKey, 5) + + // Construct an L1ValidatorWeightMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructL1ValidatorWeightMessage( + validationID, + nonce, + newValidatorWeight, + l1AInfo, + pChainInfo, + signatureAggregator, + network.GetNetworkID(), + ) + + // Deliver the Warp message to the L1 + receipt = utils.CompleteDelegatorRegistration( + ctx, + fundedKey, + delegationID, + l1AInfo, + stakingManagerProxy.Address, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseCompletedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + + // + // Disable the validator on the P-Chain + // + log.Println("Disabling the validator on the P-Chain") + _, err = network.GetPChainWallet(validationID).IssueDisableL1ValidatorTx( + validationID, + ) + Expect(err).Should(BeNil()) + utils.PChainProposerVMWorkaround(network.GetPChainWallet()) + utils.AdvanceProposerVM(ctx, l1AInfo, fundedKey, 5) + + // + // Delist the delegator + // + { + log.Println("Delisting delegator") + nonce := uint64(2) + receipt := utils.InitiateDelegatorRemoval( + ctx, + fundedKey, + l1AInfo, + stakingManagerProxy.Address, + delegationID, + ) + delegatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseInitiatedDelegatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Gather subnet-evm Warp signatures for the SetL1ValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := utils.ConstructSignedWarpMessage( + context.Background(), + receipt, + l1AInfo, + pChainInfo, + nil, + signatureAggregator, + ) + Expect(err).Should(BeNil()) + + // Issue a tx to update the validator's weight on the P-Chain + _, err = network.GetPChainWallet().IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + Expect(err).Should(BeNil()) + utils.PChainProposerVMWorkaround(network.GetPChainWallet()) + utils.AdvanceProposerVM(ctx, l1AInfo, fundedKey, 5) + + // Construct an L1ValidatorWeightMessage Warp message from the P-Chain + signedMessage := utils.ConstructL1ValidatorWeightMessage( + validationID, + nonce, + nodes[0].Weight, + l1AInfo, + pChainInfo, + signatureAggregator, + network.GetNetworkID(), + ) + + // Deliver the Warp message to the L1 + receipt = utils.CompleteDelegatorRemoval( + ctx, + fundedKey, + delegationID, + l1AInfo, + stakingManagerProxy.Address, + signedMessage, + ) + + // Check that the delegator has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseCompletedDelegatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Check that the delegator's stake was returned within an error + // margin of the weight to value factor + delegatorBalanceAfter, err := erc20.BalanceOf(&bind.CallOpts{}, fundedAddress) + Expect(err).Should(BeNil()) + diff := new(big.Int).Sub(delegatorBalance, delegatorBalanceAfter) + diff.Abs(diff) + Expect(diff.Cmp(big.NewInt(int64(utils.DefaultWeightToValueFactor)))).Should(Equal(-1)) + } +} diff --git a/icm-contracts/tests/flows/validator-manager/erc20_token_staking.go b/icm-contracts/tests/flows/validator-manager/erc20_token_staking.go new file mode 100644 index 000000000..6783d9361 --- /dev/null +++ b/icm-contracts/tests/flows/validator-manager/erc20_token_staking.go @@ -0,0 +1,288 @@ +package staking + +import ( + "context" + "log" + "math/big" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/units" + exampleerc20 "github.com/ava-labs/icm-services/abi-bindings/go/mocks/ExampleERC20" + erc20tokenstakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ERC20TokenStakingManager" + istakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/interfaces/IStakingManager" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/* + * Registers a erc20 token staking validator on a L1. The steps are as follows: + * - Deploy the ERCTokenStakingManager + * - Initiate validator registration + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the L1 + * - Verify that the validator is registered in the staking contract + * + * Delists the validator from the L1. The steps are as follows: + * - Initiate validator delisting + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the L1 + * - Verify that the validator is delisted from the staking contract + */ +func ERC20TokenStakingManager(network *localnetwork.LocalNetwork) { + // Get the L1s info + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + ctx := context.Background() + + balance := 100 * units.Avax + nodes, initialValidationIDs := network.ConvertSubnet( + ctx, + l1AInfo, + utils.ERC20TokenStakingManager, + []uint64{units.Schmeckle, 1000 * units.Schmeckle}, // Choose weights to avoid validator churn limits + []uint64{balance, balance}, + fundedKey, + false, + ) + validatorManagerProxy, stakingManagerProxy := network.GetValidatorManager(l1AInfo.SubnetID) + erc20StakingManager, err := erc20tokenstakingmanager.NewERC20TokenStakingManager( + stakingManagerProxy.Address, + l1AInfo.RPCClient, + ) + Expect(err).Should(BeNil()) + erc20Address, err := erc20StakingManager.Erc20(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + erc20, err := exampleerc20.NewExampleERC20(erc20Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + l1AInfo.SubnetID, + }, + ) + defer signatureAggregator.Shutdown() + + // + // Delist one initial validator + // + posStakingManager, err := istakingmanager.NewIStakingManager(stakingManagerProxy.Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + utils.InitiateAndCompleteEndInitialPoSValidation( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + posStakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + initialValidationIDs[0], + 0, + nodes[0].Weight, + network.GetPChainWallet(), + network.GetNetworkID(), + ) + + // + // Register the validator as PoS + // + registrationInitiatedEvent := utils.InitiateAndCompleteERC20ValidatorRegistration( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + erc20StakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + erc20, + nodes[0], + network.GetPChainWallet(), + network.GetNetworkID(), + ) + validatorStartTime := time.Now() + validationID := ids.ID(registrationInitiatedEvent.ValidationID) + + // + // Register a delegator + // + var delegationID ids.ID + { + log.Println("Registering delegator") + delegatorStake, err := erc20StakingManager.WeightToValue( + &bind.CallOpts{}, + nodes[0].Weight, + ) + Expect(err).Should(BeNil()) + delegatorStake.Div(delegatorStake, big.NewInt(10)) + delegatorWeight, err := erc20StakingManager.ValueToWeight( + &bind.CallOpts{}, + delegatorStake, + ) + Expect(err).Should(BeNil()) + newValidatorWeight := nodes[0].Weight + delegatorWeight + + nonce := uint64(1) + + receipt := utils.InitiateERC20DelegatorRegistration( + ctx, + fundedKey, + l1AInfo, + validationID, + delegatorStake, + erc20, + stakingManagerProxy.Address, + erc20StakingManager, + ) + initRegistrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseInitiatedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + delegationID = initRegistrationEvent.DelegationID + + // Gather subnet-evm Warp signatures for the L1ValidatorWeightMessage & relay to the P-Chain + signedWarpMessage := utils.ConstructSignedWarpMessage( + context.Background(), + receipt, + l1AInfo, + pChainInfo, + nil, + signatureAggregator, + ) + + // Issue a tx to update the validator's weight on the P-Chain + network.GetPChainWallet().IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network.GetPChainWallet()) + utils.AdvanceProposerVM(ctx, l1AInfo, fundedKey, 5) + + // Construct an L1ValidatorWeightMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructL1ValidatorWeightMessage( + validationID, + nonce, + newValidatorWeight, + l1AInfo, + pChainInfo, + signatureAggregator, + network.GetNetworkID(), + ) + + // Deliver the Warp message to the L1 + receipt = utils.CompleteDelegatorRegistration( + ctx, + fundedKey, + delegationID, + l1AInfo, + stakingManagerProxy.Address, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseCompletedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + + // + // Delist the delegator + // + { + log.Println("Delisting delegator") + nonce := uint64(2) + receipt := utils.InitiateDelegatorRemoval( + ctx, + fundedKey, + l1AInfo, + stakingManagerProxy.Address, + delegationID, + ) + delegatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseInitiatedDelegatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Gather subnet-evm Warp signatures for the SetL1ValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := utils.ConstructSignedWarpMessage( + context.Background(), + receipt, + l1AInfo, + pChainInfo, + nil, + signatureAggregator, + ) + Expect(err).Should(BeNil()) + + // Issue a tx to update the validator's weight on the P-Chain + network.GetPChainWallet().IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network.GetPChainWallet()) + utils.AdvanceProposerVM(ctx, l1AInfo, fundedKey, 5) + + // Construct an L1ValidatorWeightMessage Warp message from the P-Chain + signedMessage := utils.ConstructL1ValidatorWeightMessage( + validationID, + nonce, + nodes[0].Weight, + l1AInfo, + pChainInfo, + signatureAggregator, + network.GetNetworkID(), + ) + + // Deliver the Warp message to the L1 + receipt = utils.CompleteDelegatorRemoval( + ctx, + fundedKey, + delegationID, + l1AInfo, + stakingManagerProxy.Address, + signedMessage, + ) + + // Check that the delegator has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + erc20StakingManager.ParseCompletedDelegatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + + // + // Delist the validator + // + utils.InitiateAndCompleteEndPoSValidation( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + posStakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + validationID, + registrationInitiatedEvent.RegistrationExpiry, + nodes[0], + 1, + true, + validatorStartTime, + network.GetPChainWallet(), + network.GetNetworkID(), + ) +} diff --git a/icm-contracts/tests/flows/validator-manager/native_token_staking.go b/icm-contracts/tests/flows/validator-manager/native_token_staking.go new file mode 100644 index 000000000..4dd9c0190 --- /dev/null +++ b/icm-contracts/tests/flows/validator-manager/native_token_staking.go @@ -0,0 +1,280 @@ +package staking + +import ( + "context" + "log" + "math/big" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/units" + nativetokenstakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/NativeTokenStakingManager" + istakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/interfaces/IStakingManager" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +/* + * Registers a native token staking validator on a L1. The steps are as follows: + * - Deploy the NativeTokenStakingManager + * - Initiate validator registration + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the L1 + * - Verify that the validator is registered in the staking contract + * + * Delists the validator from the L1. The steps are as follows: + * - Initiate validator delisting + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the L1 + * - Verify that the validator is delisted from the staking contract + */ +func NativeTokenStakingManager(network *localnetwork.LocalNetwork) { + // Get the L1s info + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + ctx := context.Background() + + balance := 100 * units.Avax + nodes, initialValidationIDs := network.ConvertSubnet( + ctx, + l1AInfo, + utils.NativeTokenStakingManager, + []uint64{units.Schmeckle, 1000 * units.Schmeckle}, // Choose weights to avoid validator churn limits + []uint64{balance, balance}, + fundedKey, + false, + ) + validatorManagerProxy, stakingManagerProxy := network.GetValidatorManager(l1AInfo.SubnetID) + nativeStakingManager, err := nativetokenstakingmanager.NewNativeTokenStakingManager( + stakingManagerProxy.Address, + l1AInfo.RPCClient, + ) + Expect(err).Should(BeNil()) + utils.AddNativeMinterAdmin(ctx, l1AInfo, fundedKey, stakingManagerProxy.Address) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + l1AInfo.SubnetID, + }, + ) + defer signatureAggregator.Shutdown() + + // + // Delist one initial validator + // + posStakingManager, err := istakingmanager.NewIStakingManager(stakingManagerProxy.Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + utils.InitiateAndCompleteEndInitialPoSValidation( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + posStakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + initialValidationIDs[0], + 0, + nodes[0].Weight, + network.GetPChainWallet(), + network.GetNetworkID(), + ) + + // + // Register the validator as PoS + // + registrationInitiatedEvent := utils.InitiateAndCompleteNativeValidatorRegistration( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + nativeStakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + nodes[0], + network.GetPChainWallet(), + network.GetNetworkID(), + ) + validatorStartTime := time.Now() + validationID := ids.ID(registrationInitiatedEvent.ValidationID) + + // + // Register a delegator + // + var delegationID ids.ID + { + log.Println("Registering delegator") + delegatorStake, err := nativeStakingManager.WeightToValue( + &bind.CallOpts{}, + nodes[0].Weight, + ) + Expect(err).Should(BeNil()) + delegatorStake.Div(delegatorStake, big.NewInt(10)) + delegatorWeight, err := nativeStakingManager.ValueToWeight( + &bind.CallOpts{}, + delegatorStake, + ) + Expect(err).Should(BeNil()) + newValidatorWeight := nodes[0].Weight + delegatorWeight + + nonce := uint64(1) + + receipt := utils.InitiateNativeDelegatorRegistration( + ctx, + fundedKey, + l1AInfo, + validationID, + delegatorStake, + nativeStakingManager, + ) + initRegistrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + nativeStakingManager.ParseInitiatedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + delegationID = initRegistrationEvent.DelegationID + + // Gather subnet-evm Warp signatures for the L1ValidatorWeightMessage & relay to the P-Chain + signedWarpMessage := utils.ConstructSignedWarpMessage( + context.Background(), + receipt, + l1AInfo, + pChainInfo, + nil, + signatureAggregator, + ) + + // Issue a tx to update the validator's weight on the P-Chain + network.GetPChainWallet().IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network.GetPChainWallet()) + utils.AdvanceProposerVM(ctx, l1AInfo, fundedKey, 5) + + // Construct a L1ValidatorWeightMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructL1ValidatorWeightMessage( + validationID, + nonce, + newValidatorWeight, + l1AInfo, + pChainInfo, + signatureAggregator, + network.GetNetworkID(), + ) + + // Deliver the Warp message to the L1 + receipt = utils.CompleteDelegatorRegistration( + ctx, + fundedKey, + delegationID, + l1AInfo, + stakingManagerProxy.Address, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + nativeStakingManager.ParseCompletedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + // + // Delist the delegator + // + { + log.Println("Delisting delegator") + nonce := uint64(2) + receipt := utils.InitiateDelegatorRemoval( + ctx, + fundedKey, + l1AInfo, + stakingManagerProxy.Address, + delegationID, + ) + delegatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + nativeStakingManager.ParseInitiatedDelegatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Gather subnet-evm Warp signatures for the SetL1ValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := utils.ConstructSignedWarpMessage( + context.Background(), + receipt, + l1AInfo, + pChainInfo, + nil, + signatureAggregator, + ) + Expect(err).Should(BeNil()) + + // Issue a tx to update the validator's weight on the P-Chain + network.GetPChainWallet().IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + utils.PChainProposerVMWorkaround(network.GetPChainWallet()) + utils.AdvanceProposerVM(ctx, l1AInfo, fundedKey, 5) + + // Construct a L1ValidatorWeightMessage Warp message from the P-Chain + signedMessage := utils.ConstructL1ValidatorWeightMessage( + validationID, + nonce, + nodes[0].Weight, + l1AInfo, + pChainInfo, + signatureAggregator, + network.GetNetworkID(), + ) + + // Deliver the Warp message to the L1 + receipt = utils.CompleteDelegatorRemoval( + ctx, + fundedKey, + delegationID, + l1AInfo, + stakingManagerProxy.Address, + signedMessage, + ) + + // Check that the delegator has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + nativeStakingManager.ParseCompletedDelegatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + + // + // Delist the validator + // + utils.InitiateAndCompleteEndPoSValidation( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + posStakingManager, + stakingManagerProxy.Address, + validatorManagerProxy.Address, + validationID, + registrationInitiatedEvent.RegistrationExpiry, + nodes[0], + 1, + true, + validatorStartTime, + network.GetPChainWallet(), + network.GetNetworkID(), + ) +} diff --git a/icm-contracts/tests/flows/validator-manager/poa_to_pos.go b/icm-contracts/tests/flows/validator-manager/poa_to_pos.go new file mode 100644 index 000000000..afb708463 --- /dev/null +++ b/icm-contracts/tests/flows/validator-manager/poa_to_pos.go @@ -0,0 +1,245 @@ +package staking + +import ( + "context" + "math/big" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/units" + nativetokenstakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/NativeTokenStakingManager" + poamanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/PoAManager" + validatormanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ValidatorManager" + istakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/interfaces/IStakingManager" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + + . "github.com/onsi/gomega" +) + +/* + * Register a PoA validator manager on a L1 with a proxy. The steps are as follows: + * - Generate random address to be the owner address + * - Fund native assets to the owner address + * - Deploy the PoAValidatorManager contract + * - Deploy a TransparentUpgradeableProxy contract that points to the PoAValidatorManager + * - Call initialize on the PoAValidatorManager through the proxy + * - Initialize and complete PoA validator registration + * + * Migrates the proxy to a PoS validator manager. The steps are as follows: + * - Deploy the StakingManager contract + * - Upgrade the TransparentUpgradeableProxy to point to the StakingManager + * - Call initialize on the StakingManager through the proxy + * - Check that previous validator is still active + * - Initialize and complete PoS validator registration + * - Attempt to delist previous PoA validator with wrong owner and check that it fails + * - Delist the previous PoA validator properly + * - Delist the PoS validator + */ +func PoAMigrationToPoS(network *localnetwork.LocalNetwork) { + cChainInfo := network.GetPrimaryNetworkInfo() + l1AInfo, _ := network.GetTwoL1s() + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + // Generate random address to be the owner address + ownerKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + ownerAddress := crypto.PubkeyToAddress(ownerKey.PublicKey) + + // Transfer native assets to the owner account + ctx := context.Background() + fundAmount := big.NewInt(1e18) // 10avax + fundAmount.Mul(fundAmount, big.NewInt(10)) + utils.SendNativeTransfer( + ctx, + l1AInfo, + fundedKey, + ownerAddress, + fundAmount, + ) + + balance := 100 * units.Avax + // Deploy PoAManager + nodes, initialValidationIDs := network.ConvertSubnet( + ctx, + l1AInfo, + utils.PoAValidatorManager, + []uint64{units.Schmeckle, 1000 * units.Schmeckle}, // Choose weights to avoid validator churn limits + []uint64{balance, balance}, + ownerKey, + false, + ) + validatorManagerAddr, poaManagerAddr := network.GetValidatorManager(l1AInfo.SubnetID) + poaManager, err := poamanager.NewPoAManager(poaManagerAddr.Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + validatorManager, err := validatormanager.NewValidatorManager(validatorManagerAddr.Address, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + l1AInfo.SubnetID, + }, + ) + defer signatureAggregator.Shutdown() + + // + // Delist one initial validator + // + utils.InitiateAndCompleteEndInitialPoAValidation( + ctx, + signatureAggregator, + ownerKey, + l1AInfo, + pChainInfo, + poaManager, + poaManagerAddr.Address, + validatorManagerAddr.Address, + initialValidationIDs[0], + 0, + nodes[0].Weight, + network.GetPChainWallet(), + network.GetNetworkID(), + ) + + // Try to call with invalid owner + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1AInfo.EVMChainID) + Expect(err).Should(BeNil()) + + _, err = poaManager.InitiateValidatorRegistration( + opts, + nodes[0].NodeID[:], + nodes[0].NodePoP.PublicKey[:], + poamanager.PChainOwner{}, + poamanager.PChainOwner{}, + nodes[0].Weight, + ) + Expect(err).ShouldNot(BeNil()) + + // + // Re-register the validator as a SoV validator + // + expiry := uint64(time.Now().Add(24 * time.Hour).Unix()) + registrationInitiatedEvent := utils.InitiateAndCompletePoAValidatorRegistration( + ctx, + signatureAggregator, + ownerKey, + l1AInfo, + pChainInfo, + poaManager, + poaManagerAddr.Address, + validatorManagerAddr.Address, + expiry, + nodes[0], + network.GetPChainWallet(), + network.GetNetworkID(), + ) + poaValidationID := registrationInitiatedEvent.ValidationID + + poaValidator, err := validatorManager.GetValidator(&bind.CallOpts{}, poaValidationID) + Expect(err).Should(BeNil()) + poaNodeID := poaValidator.NodeID + + /* + ****************** + * Migrate PoAValidatorManager to StakingManager + ****************** + */ + + // Deploy StakingManager contract + stakingManagerAddress, _ := utils.DeployAndInitializeValidatorManagerSpecialization( + ctx, + ownerKey, + l1AInfo, + validatorManagerAddr.Address, + utils.NativeTokenStakingManager, + false, + ) + + utils.AddNativeMinterAdmin(ctx, l1AInfo, fundedKey, stakingManagerAddress) + + nativeStakingManager, err := nativetokenstakingmanager.NewNativeTokenStakingManager( + stakingManagerAddress, + l1AInfo.RPCClient, + ) + Expect(err).Should(BeNil()) + + // Transfer ownership from PoA -> the new staking manager + opts, err = bind.NewKeyedTransactorWithChainID(ownerKey, l1AInfo.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := poaManager.TransferValidatorManagerOwnership(opts, stakingManagerAddress) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(context.Background(), l1AInfo, tx.Hash()) + + // Check that previous validator is still registered + validationID, err := validatorManager.GetNodeValidationID(&bind.CallOpts{}, poaNodeID) + Expect(err).Should(BeNil()) + Expect(validationID[:]).Should(Equal(poaValidationID[:])) + + validator, err := validatorManager.GetValidator(&bind.CallOpts{}, validationID) + Expect(err).Should(BeNil()) + Expect(validator.EndTime).Should(Equal(uint64(0))) + + // + // Remove the PoA validator and re-register as a PoS validator + // + posStakingManager, err := istakingmanager.NewIStakingManager(stakingManagerAddress, l1AInfo.RPCClient) + Expect(err).Should(BeNil()) + utils.InitiateAndCompleteEndPoSValidation( + ctx, + signatureAggregator, + ownerKey, + l1AInfo, + pChainInfo, + posStakingManager, + stakingManagerAddress, + validatorManagerAddr.Address, + poaValidationID, + registrationInitiatedEvent.RegistrationExpiry, + nodes[0], + 1, + false, + time.Time{}, + network.GetPChainWallet(), + network.GetNetworkID(), + ) + + posRegistrationInitiatedEvent := utils.InitiateAndCompleteNativeValidatorRegistration( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + nativeStakingManager, + stakingManagerAddress, + validatorManagerAddr.Address, + nodes[0], + network.GetPChainWallet(), + network.GetNetworkID(), + ) + validatorStartTime := time.Now() + posValidationID := posRegistrationInitiatedEvent.ValidationID + + // Delist the PoS validator + utils.InitiateAndCompleteEndPoSValidation( + ctx, + signatureAggregator, + fundedKey, + l1AInfo, + pChainInfo, + posStakingManager, + stakingManagerAddress, + validatorManagerAddr.Address, + posValidationID, + posRegistrationInitiatedEvent.RegistrationExpiry, + nodes[0], + 1, + true, + validatorStartTime, + network.GetPChainWallet(), + network.GetNetworkID(), + ) +} diff --git a/icm-contracts/tests/interfaces/subnet_test_info.go b/icm-contracts/tests/interfaces/subnet_test_info.go new file mode 100644 index 000000000..3ec4d0690 --- /dev/null +++ b/icm-contracts/tests/interfaces/subnet_test_info.go @@ -0,0 +1,19 @@ +package interfaces + +import ( + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/subnet-evm/ethclient" +) + +// Tracks information about a test L1 used for executing tests against. +type L1TestInfo struct { + SubnetID ids.ID + BlockchainID ids.ID + NodeURIs []string + WSClient ethclient.Client + RPCClient ethclient.Client + EVMChainID *big.Int + RequirePrimaryNetworkSigners bool +} diff --git a/icm-contracts/tests/network/network.go b/icm-contracts/tests/network/network.go new file mode 100644 index 000000000..e6ebaa065 --- /dev/null +++ b/icm-contracts/tests/network/network.go @@ -0,0 +1,711 @@ +package network + +import ( + "context" + "crypto/ecdsa" + "encoding/base64" + "encoding/hex" + "encoding/json" + "io/fs" + goLog "log" + "os" + "sort" + "time" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/formatting/address" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/platformvm" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + warpMessage "github.com/ava-labs/avalanchego/vms/platformvm/warp/message" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + pwallet "github.com/ava-labs/avalanchego/wallet/chain/p/wallet" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" + ownableupgradeable "github.com/ava-labs/icm-services/abi-bindings/go/OwnableUpgradeable" + proxyadmin "github.com/ava-labs/icm-services/abi-bindings/go/ProxyAdmin" + validatormanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ValidatorManager" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/ethclient" + subnetEvmTestUtils "github.com/ava-labs/subnet-evm/tests/utils" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + . "github.com/onsi/gomega" +) + +type ProxyAddress struct { + common.Address + *proxyadmin.ProxyAdmin +} + +// Implements Network, pointing to the network setup in local_network_setup.go +type LocalNetwork struct { + *tmpnet.Network + + extraNodes []*tmpnet.Node // to add as more L1 validators in the tests + primaryNetworkValidators []*tmpnet.Node + globalFundedKey *secp256k1.PrivateKey + validatorManagers map[ids.ID]ProxyAddress + validatorManagerSpecializations map[ids.ID]ProxyAddress + logger logging.Logger + deployedL1Specs map[string]L1Spec +} + +const ( + fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" + timeout = 120 * time.Second +) + +type L1Spec struct { + Name string + EVMChainID uint64 + NodeCount int + + // Optional fields + TeleporterContractAddress common.Address + TeleporterDeployedBytecode string + TeleporterDeployerAddress common.Address + RequirePrimaryNetworkSigners bool +} + +func newTmpnetNetwork( + name string, + globalFundedKey *secp256k1.PrivateKey, + warpGenesisTemplateFile string, + numPrimaryNetworkValidators int, + l1Specs []L1Spec, + flagVars *e2e.FlagVars, +) *tmpnet.Network { + var l1s []*tmpnet.Subnet + + bootstrapNodes := subnetEvmTestUtils.NewTmpnetNodes(numPrimaryNetworkValidators) + for i, l1Spec := range l1Specs { + // Create a single bootstrap node. This will be removed from the L1 validator set after it is converted, + // but will remain a primary network validator + initialL1Bootstrapper := bootstrapNodes[i] // One bootstrap node per L1 + + l1 := subnetEvmTestUtils.NewTmpnetSubnet( + l1Spec.Name, + utils.InstantiateGenesisTemplate( + warpGenesisTemplateFile, + l1Spec.EVMChainID, + l1Spec.TeleporterContractAddress, + l1Spec.TeleporterDeployedBytecode, + l1Spec.TeleporterDeployerAddress, + l1Spec.RequirePrimaryNetworkSigners, + ), + utils.WarpEnabledChainConfig, + initialL1Bootstrapper, + ) + l1.OwningKey = globalFundedKey + l1s = append(l1s, l1) + } + + // Create new network + network := subnetEvmTestUtils.NewTmpnetNetwork( + name, + bootstrapNodes, + tmpnet.FlagsMap{}, + l1s..., + ) + + Expect(network).ShouldNot(BeNil()) + + // Specify only a subset of the nodes to be bootstrapped + keysToFund := []*secp256k1.PrivateKey{ + genesis.VMRQKey, + genesis.EWOQKey, + tmpnet.HardhatKey, + } + keysToFund = append(keysToFund, network.PreFundedKeys...) + genesis, err := tmpnet.NewTestGenesis(88888, bootstrapNodes, keysToFund) + Expect(err).Should(BeNil()) + network.Genesis = genesis + network.PreFundedKeys = keysToFund + + runtimeCfg, err := flagVars.NodeRuntimeConfig() + Expect(err).Should(BeNil()) + runtimeCfg.Process.ReuseDynamicPorts = true + network.DefaultRuntimeConfig = *runtimeCfg + + return network +} + +func NewLocalNetwork( + ctx context.Context, + name string, + warpGenesisTemplateFile string, + l1Specs []L1Spec, + numPrimaryNetworkValidators int, + extraNodeCount int, // for use by tests, eg to add new L1 validators + flagVars *e2e.FlagVars, +) *LocalNetwork { + // There must be at least one primary network validator per L1 + Expect(numPrimaryNetworkValidators).Should(BeNumerically(">=", len(l1Specs))) + + // Create extra nodes to be used to add more validators later + extraNodes := subnetEvmTestUtils.NewTmpnetNodes(extraNodeCount) + + for _, l1Spec := range l1Specs { + initialVdrNodes := subnetEvmTestUtils.NewTmpnetNodes(l1Spec.NodeCount) + extraNodes = append(extraNodes, initialVdrNodes...) + } + + fundedKey, err := hex.DecodeString(fundedKeyStr) + Expect(err).Should(BeNil()) + globalFundedKey, err := secp256k1.ToPrivateKey(fundedKey) + Expect(err).Should(BeNil()) + + globalFundedECDSAKey := globalFundedKey.ToECDSA() + Expect(err).Should(BeNil()) + + deployedL1Specs := make(map[string]L1Spec) + for _, l1Spec := range l1Specs { + deployedL1Specs[l1Spec.Name] = l1Spec + } + + isReuseNetwork := flagVars != nil && flagVars.NetworkDir() != "" + + var network *tmpnet.Network + // All nodes are specified as bootstrap validators + var primaryNetworkValidators []*tmpnet.Node + if isReuseNetwork { + // Load existing network and restart nodes + network, err = tmpnet.ReadNetwork(context.Background(), logging.NoLog{}, flagVars.NetworkDir()) + Expect(err).Should(BeNil()) + Expect(network).ShouldNot(BeNil()) + + extraNodes = make([]*tmpnet.Node, 0) + for _, node := range network.Nodes { + err := node.Restart(ctx) + Expect(err).Should(BeNil(), "Failed to restart node %s: %v", node.NodeID, err) + + if node.Flags[config.PartialSyncPrimaryNetworkKey] == "true" { + extraNodes = append(extraNodes, node) + } else { + primaryNetworkValidators = append(primaryNetworkValidators, node) + } + } + + err := tmpnet.WaitForHealthyNodes(ctx, logging.NoLog{}, network.Nodes) + Expect(err).Should(BeNil()) + } else { + network = newTmpnetNetwork( + name, + globalFundedKey, + warpGenesisTemplateFile, + numPrimaryNetworkValidators, + l1Specs, + flagVars, + ) + + primaryNetworkValidators = append(primaryNetworkValidators, network.Nodes...) + } + + goLog.Println("flagVars.ActivateGranite()", flagVars.ActivateGranite()) + upgrades := upgrade.Default + if flagVars.ActivateGranite() { + upgrades.GraniteTime = upgrade.InitiallyActiveTime + upgrades.GraniteEpochDuration = 4 * time.Second + } else { + upgrades.GraniteTime = upgrade.UnscheduledActivationTime + } + + upgradeJSON, err := json.Marshal(upgrades) + Expect(err).Should(BeNil()) + + upgradeBase64 := base64.StdEncoding.EncodeToString(upgradeJSON) + + defaultFlags := tmpnet.FlagsMap{ + config.UpgradeFileContentKey: upgradeBase64, + } + defaultFlags.SetDefaults(tmpnet.DefaultE2EFlags()) + network.DefaultFlags = defaultFlags + + tc := e2e.NewTestContext() + env := e2e.NewTestEnvironment(tc, flagVars, network) + Expect(env).ShouldNot(BeNil()) + + ctx, cancelBootstrap := context.WithCancel(ctx) + defer cancelBootstrap() + + logger := logging.NewLogger("tmpnet") + goLog.Println("Network bootstrapped") + + // Issue transactions to activate the proposerVM fork on the chains + if !isReuseNetwork { + for _, l1 := range network.Subnets { + utils.SetupProposerVM(ctx, globalFundedECDSAKey, network, l1.SubnetID) + } + } + + localNetwork := &LocalNetwork{ + Network: network, + extraNodes: extraNodes, + globalFundedKey: globalFundedKey, + primaryNetworkValidators: primaryNetworkValidators, + validatorManagers: make(map[ids.ID]ProxyAddress), + validatorManagerSpecializations: make(map[ids.ID]ProxyAddress), + logger: logger, + deployedL1Specs: deployedL1Specs, + } + + return localNetwork +} + +func (n *LocalNetwork) ConvertSubnet( + ctx context.Context, + l1 interfaces.L1TestInfo, + managerType utils.ValidatorManagerConcreteType, + weights []uint64, + balances []uint64, + senderKey *ecdsa.PrivateKey, + proxy bool, +) ([]utils.Node, []ids.ID) { + Expect(len(weights)).Should(Equal(len(balances))) + goLog.Println("Converting l1", l1.SubnetID) + cChainInfo := n.GetPrimaryNetworkInfo() + pClient := platformvm.NewClient(cChainInfo.NodeURIs[0]) + currentValidators, err := pClient.GetCurrentValidators(ctx, l1.SubnetID, nil) + Expect(err).Should(BeNil()) + + vdrManagerAddress, vdrManagerProxyAdmin := utils.DeployValidatorManager( + ctx, + senderKey, + l1, + proxy, + ) + + validatorManager, err := validatormanager.NewValidatorManager(vdrManagerAddress, l1.RPCClient) + Expect(err).Should(BeNil()) + + sender := utils.PrivateKeyToAddress(senderKey) + + utils.InitializeValidatorManager( + ctx, + senderKey, + l1, + validatorManager, + sender, + ) + + n.validatorManagers[l1.SubnetID] = ProxyAddress{ + Address: vdrManagerAddress, + ProxyAdmin: vdrManagerProxyAdmin, + } + + specializationAddress, specializationProxyAdmin := utils.DeployAndInitializeValidatorManagerSpecialization( + ctx, + senderKey, + l1, + vdrManagerAddress, + managerType, + proxy, + ) + + ownable, err := ownableupgradeable.NewOwnableUpgradeable(vdrManagerAddress, l1.RPCClient) + Expect(err).Should(BeNil()) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := ownable.TransferOwnership(opts, specializationAddress) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(context.Background(), l1, tx.Hash()) + + n.validatorManagerSpecializations[l1.SubnetID] = ProxyAddress{ + Address: specializationAddress, + ProxyAdmin: specializationProxyAdmin, + } + + tmpnetNodes := n.GetExtraNodes(len(weights)) + sort.Slice(tmpnetNodes, func(i, j int) bool { + return string(tmpnetNodes[i].NodeID.Bytes()) < string(tmpnetNodes[j].NodeID.Bytes()) + }) + + var nodes []utils.Node + // Construct the converted l1 info + destAddr, err := address.ParseToID(utils.DefaultPChainAddress) + Expect(err).Should(BeNil()) + vdrs := make([]*txs.ConvertSubnetToL1Validator, len(tmpnetNodes)) + for i, node := range tmpnetNodes { + signer, err := node.GetProofOfPossession() + Expect(err).Should(BeNil()) + nodes = append(nodes, utils.Node{ + NodeID: node.NodeID, + NodePoP: signer, + Weight: weights[i], + }) + vdrs[i] = &txs.ConvertSubnetToL1Validator{ + NodeID: node.NodeID.Bytes(), + Weight: weights[i], + Balance: balances[i], + Signer: *signer, + RemainingBalanceOwner: warpMessage.PChainOwner{ + Threshold: 1, + Addresses: []ids.ShortID{destAddr}, + }, + DeactivationOwner: warpMessage.PChainOwner{ + Threshold: 1, + Addresses: []ids.ShortID{destAddr}, + }, + } + } + pChainWallet := n.GetPChainWallet() + _, err = pChainWallet.IssueConvertSubnetToL1Tx( + l1.SubnetID, + l1.BlockchainID, + vdrManagerAddress[:], + vdrs, + ) + Expect(err).Should(BeNil()) + + l1 = n.AddSubnetValidators(tmpnetNodes, l1, true) + + utils.PChainProposerVMWorkaround(pChainWallet) + utils.AdvanceProposerVM(ctx, l1, senderKey, 5) + + aggregator := n.GetSignatureAggregator() + defer aggregator.Shutdown() + validationIDs := utils.InitializeValidatorSet( + ctx, + senderKey, + l1, + utils.GetPChainInfo(cChainInfo), + vdrManagerAddress, + n.GetNetworkID(), + aggregator, + nodes, + ) + + // Remove the bootstrap nodes as l1 validators + for _, vdr := range currentValidators { + _, err := pChainWallet.IssueRemoveSubnetValidatorTx(vdr.NodeID, l1.SubnetID) + Expect(err).Should(BeNil()) + for _, node := range n.Network.Nodes { + if node.NodeID == vdr.NodeID { + Expect(n.Network.DefaultRuntimeConfig).ShouldNot(BeNil()) + Expect(n.Network.DefaultRuntimeConfig.Process.ReuseDynamicPorts).Should(BeTrue()) + node.RuntimeConfig = &n.Network.DefaultRuntimeConfig + goLog.Println("Restarting bootstrap node", node.NodeID) + err = node.Restart(ctx) + Expect(err).Should(BeNil()) + } + } + } + utils.PChainProposerVMWorkaround(pChainWallet) + utils.IssueTxsToAdvanceChain(ctx, l1.EVMChainID, senderKey, l1.RPCClient, 5) + + return nodes, validationIDs +} + +func (n *LocalNetwork) AddSubnetValidators( + nodes []*tmpnet.Node, + l1 interfaces.L1TestInfo, + partialSync bool, +) interfaces.L1TestInfo { + // Modify the each node's config to track the l1 + for _, node := range nodes { + goLog.Printf("Adding node %s @ %s to l1 %s", node.NodeID, node.URI, l1.SubnetID) + existingTrackedSubnets := node.Flags[config.TrackSubnetsKey] + if existingTrackedSubnets == l1.SubnetID.String() { + goLog.Printf("Node %s @ %s already tracking l1 %s\n", node.NodeID, node.URI, l1.SubnetID) + continue + } + node.Flags[config.TrackSubnetsKey] = l1.SubnetID.String() + + if partialSync { + node.Flags[config.PartialSyncPrimaryNetworkKey] = "true" + } + + // Add the node to the network + n.Network.Nodes = append(n.Network.Nodes, node) + } + err := n.Network.StartNodes(context.Background(), n.logger, nodes...) + Expect(err).Should(BeNil()) + + // Update the tmpnet Subnet struct + for _, tmpnetSubnet := range n.Network.Subnets { + if tmpnetSubnet.SubnetID == l1.SubnetID { + for _, tmpnetNode := range nodes { + tmpnetSubnet.ValidatorIDs = append(tmpnetSubnet.ValidatorIDs, tmpnetNode.NodeID) + } + } + } + + // Refresh the l1 info after restarting the nodes + return n.GetL1Info(l1.SubnetID) +} + +func (n *LocalNetwork) GetValidatorManager(subnetID ids.ID) (ProxyAddress, ProxyAddress) { + return n.validatorManagers[subnetID], n.validatorManagerSpecializations[subnetID] +} + +func (n *LocalNetwork) GetSignatureAggregator() *utils.SignatureAggregator { + var subnetIDs []ids.ID + for _, l1 := range n.GetL1Infos() { + subnetIDs = append(subnetIDs, l1.SubnetID) + } + return utils.NewSignatureAggregator( + n.GetPrimaryNetworkInfo().NodeURIs[0], + subnetIDs, + ) +} + +func (n *LocalNetwork) GetExtraNodes(count int) []*tmpnet.Node { + Expect(len(n.extraNodes) >= count).Should( + BeTrue(), + "not enough extra nodes to use", + ) + nodes := n.extraNodes[0:count] + n.extraNodes = n.extraNodes[count:] + return nodes +} + +func (n *LocalNetwork) GetPrimaryNetworkValidators() []*tmpnet.Node { + return n.primaryNetworkValidators +} + +func (n *LocalNetwork) GetPrimaryNetworkInfo() interfaces.L1TestInfo { + var nodeURIs []string + for _, node := range n.primaryNetworkValidators { + nodeURIs = append(nodeURIs, node.URI) + } + infoClient := info.NewClient(nodeURIs[0]) + cChainBlockchainID, err := infoClient.GetBlockchainID(context.Background(), "C") + Expect(err).Should(BeNil()) + + wsClient, err := ethclient.Dial(utils.HttpToWebsocketURI(nodeURIs[0], cChainBlockchainID.String())) + Expect(err).Should(BeNil()) + + rpcClient, err := ethclient.Dial(utils.HttpToRPCURI(nodeURIs[0], cChainBlockchainID.String())) + Expect(err).Should(BeNil()) + + evmChainID, err := rpcClient.ChainID(context.Background()) + Expect(err).Should(BeNil()) + return interfaces.L1TestInfo{ + SubnetID: ids.Empty, + BlockchainID: cChainBlockchainID, + NodeURIs: nodeURIs, + WSClient: wsClient, + RPCClient: rpcClient, + EVMChainID: evmChainID, + RequirePrimaryNetworkSigners: false, + } +} + +func (n *LocalNetwork) GetL1Info(subnetID ids.ID) interfaces.L1TestInfo { + for _, l1 := range n.Network.Subnets { + if l1.SubnetID == subnetID { + var nodeURIs []string + for _, nodeID := range l1.ValidatorIDs { + node, err := n.Network.GetNode(nodeID) + Expect(err).Should(BeNil()) + + nodeURIs = append(nodeURIs, node.URI) + } + blockchainID := l1.Chains[0].ChainID + wsClient, err := ethclient.Dial(utils.HttpToWebsocketURI(nodeURIs[0], blockchainID.String())) + Expect(err).Should(BeNil()) + + rpcClient, err := ethclient.Dial(utils.HttpToRPCURI(nodeURIs[0], blockchainID.String())) + Expect(err).Should(BeNil()) + evmChainID, err := rpcClient.ChainID(context.Background()) + Expect(err).Should(BeNil()) + spec, ok := n.deployedL1Specs[l1.Name] + Expect(ok).Should(BeTrue()) + return interfaces.L1TestInfo{ + SubnetID: subnetID, + BlockchainID: blockchainID, + NodeURIs: nodeURIs, + WSClient: wsClient, + RPCClient: rpcClient, + EVMChainID: evmChainID, + RequirePrimaryNetworkSigners: spec.RequirePrimaryNetworkSigners, + } + } + } + return interfaces.L1TestInfo{} +} + +// Returns all l1 info sorted in lexicographic order of L1Name. +func (n *LocalNetwork) GetL1Infos() []interfaces.L1TestInfo { + l1s := make([]interfaces.L1TestInfo, len(n.Network.Subnets)) + for i, l1 := range n.Network.Subnets { + var nodeURIs []string + for _, nodeID := range l1.ValidatorIDs { + node, err := n.Network.GetNode(nodeID) + Expect(err).Should(BeNil()) + + nodeURIs = append(nodeURIs, node.URI) + } + blockchainID := l1.Chains[0].ChainID + wsClient, err := ethclient.Dial(utils.HttpToWebsocketURI(nodeURIs[0], blockchainID.String())) + Expect(err).Should(BeNil()) + + rpcClient, err := ethclient.Dial(utils.HttpToRPCURI(nodeURIs[0], blockchainID.String())) + Expect(err).Should(BeNil()) + evmChainID, err := rpcClient.ChainID(context.Background()) + Expect(err).Should(BeNil()) + spec, ok := n.deployedL1Specs[l1.Name] + Expect(ok).Should(BeTrue()) + l1s[i] = interfaces.L1TestInfo{ + SubnetID: l1.SubnetID, + BlockchainID: blockchainID, + NodeURIs: nodeURIs, + WSClient: wsClient, + RPCClient: rpcClient, + EVMChainID: evmChainID, + RequirePrimaryNetworkSigners: spec.RequirePrimaryNetworkSigners, + } + } + return l1s +} + +// Returns L1 info for all L1s, including the primary network +func (n *LocalNetwork) GetAllL1Infos() []interfaces.L1TestInfo { + l1s := n.GetL1Infos() + return append(l1s, n.GetPrimaryNetworkInfo()) +} + +func (n *LocalNetwork) GetFundedAccountInfo() (common.Address, *ecdsa.PrivateKey) { + ecdsaKey := n.globalFundedKey.ToECDSA() + fundedAddress := crypto.PubkeyToAddress(ecdsaKey.PublicKey) + return fundedAddress, ecdsaKey +} + +func (n *LocalNetwork) TearDownNetwork() { + log.Info("Tearing down network") + Expect(n).ShouldNot(BeNil()) + Expect(n.Network).ShouldNot(BeNil()) + Expect(n.Network.Stop(context.Background())).Should(BeNil()) +} + +func (n *LocalNetwork) SetChainConfigs(chainConfigs map[string]string) { + for chainIDStr, chainConfig := range chainConfigs { + var cfg tmpnet.ConfigMap + err := json.Unmarshal([]byte(chainConfig), &cfg) + if err != nil { + log.Error( + "failed to unmarshal chain config", + "error", err, + "chainConfig", chainConfig, + ) + } + if chainIDStr == utils.CChainPathSpecifier { + n.Network.PrimarySubnetConfig = cfg + n.Network.PrimaryChainConfigs[utils.CChainPathSpecifier] = cfg + continue + } + + for _, l1 := range n.Network.Subnets { + for _, chain := range l1.Chains { + if chain.ChainID.String() == chainIDStr { + chain.Config = chainConfig + } + } + } + } + err := n.Network.Write() + if err != nil { + log.Error("failed to write network", "error", err) + } + + for _, l1 := range n.Network.Subnets { + err := l1.Write(n.Network.GetSubnetDir()) + if err != nil { + log.Error("failed to write L1s", "error", err) + } + } + + // Restart the network to apply the new chain configs + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(60*len(n.Network.Nodes))*time.Second) + defer cancel() + err = n.Network.Restart(ctx) + Expect(err).Should(BeNil()) +} + +func (n *LocalNetwork) GetNetworkID() uint32 { + return n.Network.Genesis.NetworkID +} + +func (n *LocalNetwork) Dir() string { + return n.Network.Dir +} + +func (n *LocalNetwork) GetPChainWallet(validationIDs ...ids.ID) pwallet.Wallet { + // Create the P-Chain wallet to issue transactions + kc := secp256k1fx.NewKeychain(n.globalFundedKey) + var subnetIDs []ids.ID + for _, l1 := range n.GetL1Infos() { + subnetIDs = append(subnetIDs, l1.SubnetID) + } + wallet, err := primary.MakeWallet( + context.Background(), + n.GetPrimaryNetworkInfo().NodeURIs[0], + kc, + kc, + primary.WalletConfig{ + SubnetIDs: subnetIDs, + ValidationIDs: validationIDs, + }) + Expect(err).Should(BeNil()) + return wallet.P() +} + +func (n *LocalNetwork) GetTwoL1s() ( + interfaces.L1TestInfo, + interfaces.L1TestInfo, +) { + l1s := n.GetL1Infos() + Expect(len(l1s)).Should(BeNumerically(">=", 2)) + return l1s[0], l1s[1] +} + +func (n *LocalNetwork) SaveValidatorAddress( + fileName string, +) { + validatorAddresses := make(map[string]map[string]string) + for _, subnet := range n.GetL1Infos() { + validator, validatorSpec := n.GetValidatorManager(subnet.SubnetID) + validatorAddresses[subnet.BlockchainID.Hex()] = make(map[string]string) + validatorAddresses[subnet.BlockchainID.Hex()]["validator"] = validator.Address.Hex() + validatorAddresses[subnet.BlockchainID.Hex()]["spec"] = validatorSpec.Address.Hex() + } + + jsonData, err := json.Marshal(validatorAddresses) + Expect(err).Should(BeNil()) + err = os.WriteFile(fileName, jsonData, fs.ModePerm) + Expect(err).Should(BeNil()) +} + +func (n *LocalNetwork) SetValidatorAddressFromFile(fileName string) { + validatorAddresses := make(map[string]map[string]string) + data, err := os.ReadFile(fileName) + Expect(err).Should(BeNil()) + err = json.Unmarshal(data, &validatorAddresses) + Expect(err).Should(BeNil()) + + // Set the validator manager for each L1 + for _, subnet := range n.GetL1Infos() { + validatorAddress := common.HexToAddress(validatorAddresses[subnet.BlockchainID.Hex()]["validator"]) + validatorSpecAddress := common.HexToAddress(validatorAddresses[subnet.BlockchainID.Hex()]["spec"]) + + n.validatorManagers[subnet.SubnetID] = ProxyAddress{ + Address: validatorAddress, + } + n.validatorManagerSpecializations[subnet.SubnetID] = ProxyAddress{ + Address: validatorSpecAddress, + } + } +} diff --git a/icm-contracts/tests/suites/governance/governance_suite_test.go b/icm-contracts/tests/suites/governance/governance_suite_test.go new file mode 100644 index 000000000..56336b41b --- /dev/null +++ b/icm-contracts/tests/suites/governance/governance_suite_test.go @@ -0,0 +1,83 @@ +package governance_test + +import ( + "context" + "flag" + "os" + "testing" + "time" + + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + governanceFlows "github.com/ava-labs/icm-services/icm-contracts/tests/flows/governance" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/libevm/log" + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" + validatorSetSigLabel = "ValidatorSetSig" +) + +var ( + LocalNetworkInstance *localnetwork.LocalNetwork + e2eFlags *e2e.FlagVars +) + +func TestMain(m *testing.M) { + e2eFlags = e2e.RegisterFlags() + flag.Parse() + os.Exit(m.Run()) +} + +func TestGovernance(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + + RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "Governance e2e test") +} + +// Define the before and after suite functions. +var _ = ginkgo.BeforeSuite(func() { + // Create the local network instance + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + LocalNetworkInstance = localnetwork.NewLocalNetwork( + ctx, + "governance-test-local-network", + warpGenesisTemplateFile, + []localnetwork.L1Spec{ + { + Name: "A", + EVMChainID: 12345, + NodeCount: 2, + }, + { + Name: "B", + EVMChainID: 54321, + NodeCount: 2, + }, + }, + 2, + 2, + e2eFlags, + ) + log.Info("Started local network") +}) + +var _ = ginkgo.AfterSuite(func() { + LocalNetworkInstance.TearDownNetwork() + LocalNetworkInstance = nil +}) + +var _ = ginkgo.Describe("[Governance integration tests]", func() { + // Governance tests + ginkgo.It("Deliver ValidatorSetSig signed message", + ginkgo.Label(validatorSetSigLabel), + func() { + governanceFlows.ValidatorSetSig(LocalNetworkInstance) + }) +}) diff --git a/icm-contracts/tests/suites/ictt/ictt_suite_test.go b/icm-contracts/tests/suites/ictt/ictt_suite_test.go new file mode 100644 index 000000000..95cf93f42 --- /dev/null +++ b/icm-contracts/tests/suites/ictt/ictt_suite_test.go @@ -0,0 +1,227 @@ +package ictt_test + +import ( + "context" + "flag" + "fmt" + "io/fs" + "math/big" + "os" + "testing" + "time" + + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + icttFlows "github.com/ava-labs/icm-services/icm-contracts/tests/flows/ictt" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + deploymentUtils "github.com/ava-labs/icm-services/icm-contracts/utils/deployment-utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/segmentio/encoding/json" +) + +const ( + teleporterByteCodeFile = "./out/TeleporterMessenger.sol/TeleporterMessenger.json" + warpGenesisTemplateFile = "./icm-contracts/tests/utils/warp-genesis-template.json" + + icttLabel = "ICTT" + erc20TokenHomeLabel = "ERC20TokenHome" + erc20TokenRemoteLabel = "ERC20TokenRemote" + nativeTokenHomeLabel = "NativeTokenHome" + nativeTokenRemoteLabel = "NativeTokenRemote" + multiHopLabel = "MultiHop" + sendAndCallLabel = "SendAndCall" + registrationLabel = "Registration" + upgradabilityLabel = "upgradability" + + teleporterRegistryAddressFile = "TeleporterRegistryAddress.json" +) + +var ( + LocalNetworkInstance *localnetwork.LocalNetwork + TeleporterInfo utils.TeleporterTestInfo + e2eFlags *e2e.FlagVars +) + +func TestMain(m *testing.M) { + e2eFlags = e2e.RegisterFlags() + flag.Parse() + os.Exit(m.Run()) +} + +func TestICTT(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + + RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "ICTT e2e test") +} + +// Define the Teleporter before and after suite functions. +var _ = ginkgo.BeforeSuite(func() { + // Generate the Teleporter deployment values + teleporterDeployerTransaction, + teleporterDeployedBytecode, + teleporterDeployerAddress, + teleporterContractAddress, + err := deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + Expect(err).Should(BeNil()) + + // Create the local network instance + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + LocalNetworkInstance = localnetwork.NewLocalNetwork( + ctx, + "teleporter-test-local-network", + warpGenesisTemplateFile, + []localnetwork.L1Spec{ + { + Name: "A", + EVMChainID: 12345, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + { + Name: "B", + EVMChainID: 54321, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 2, + }, + }, + 2, + 2, + e2eFlags, + ) + TeleporterInfo = utils.NewTeleporterTestInfo(LocalNetworkInstance.GetAllL1Infos()) + log.Info("Started local network") + + // Only need to deploy Teleporter on the C-Chain since it is included in the genesis of the L1 chains. + _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() + + if e2eFlags.NetworkDir() == "" { + // Only deploy Teleporter if we are not reusing an existing network + TeleporterInfo.DeployTeleporterMessenger( + ctx, + LocalNetworkInstance.GetPrimaryNetworkInfo(), + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + + for _, l1 := range LocalNetworkInstance.GetAllL1Infos() { + TeleporterInfo.SetTeleporter(teleporterContractAddress, l1) + TeleporterInfo.InitializeBlockchainID(l1, fundedKey) + TeleporterInfo.DeployTeleporterRegistry(l1, fundedKey) + } + + registryAddresseses := make(map[string]string) + for l1, teleporterInfo := range TeleporterInfo { + registryAddresseses[l1.Hex()] = teleporterInfo.TeleporterRegistryAddress.Hex() + } + + jsonData, err := json.Marshal(registryAddresseses) + Expect(err).Should(BeNil()) + err = os.WriteFile(teleporterRegistryAddressFile, jsonData, fs.ModePerm) + Expect(err).Should(BeNil()) + + } else { + fundAmount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(15)) // 11 AVAX + fundDeployerTx := utils.CreateNativeTransferTransaction( + ctx, LocalNetworkInstance.GetPrimaryNetworkInfo(), fundedKey, teleporterDeployerAddress, fundAmount, + ) + utils.SendTransactionAndWaitForSuccess(ctx, LocalNetworkInstance.GetPrimaryNetworkInfo(), fundDeployerTx) + fmt.Println("Deployer funded with", fundAmount, "AVAX") + + // Read the Teleporter registry address from the file + registryAddresseses := make(map[string]string) + data, err := os.ReadFile(teleporterRegistryAddressFile) + Expect(err).Should(BeNil()) + err = json.Unmarshal(data, ®istryAddresseses) + Expect(err).Should(BeNil()) + + for _, l1 := range LocalNetworkInstance.GetAllL1Infos() { + TeleporterInfo.SetTeleporter(teleporterContractAddress, l1) + TeleporterInfo.SetTeleporterRegistry( + common.HexToAddress(registryAddresseses[l1.BlockchainID.Hex()]), + l1, + ) + } + } + +}) + +var _ = ginkgo.AfterSuite(func() { + LocalNetworkInstance.TearDownNetwork() + LocalNetworkInstance = nil +}) + +var _ = ginkgo.Describe("[ICTT integration tests]", func() { + // ICTT tests + ginkgo.It("Transfer an ERC20 token between two L1s", + ginkgo.Label(icttLabel, erc20TokenHomeLabel, erc20TokenRemoteLabel), + func() { + icttFlows.ERC20TokenHomeERC20TokenRemote(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer a native token to an ERC20 token", + ginkgo.Label(icttLabel, nativeTokenHomeLabel, erc20TokenRemoteLabel), + func() { + icttFlows.NativeTokenHomeERC20TokenRemote(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer a native token to a native token", + ginkgo.Label(icttLabel, nativeTokenHomeLabel, nativeTokenRemoteLabel), + func() { + icttFlows.NativeTokenHomeNativeDestination(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer an ERC20 token with ERC20TokenHome multi-hop", + ginkgo.Label(icttLabel, erc20TokenHomeLabel, erc20TokenRemoteLabel, multiHopLabel), + func() { + icttFlows.ERC20TokenHomeERC20TokenRemoteMultiHop(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer a native token with NativeTokenHome multi-hop", + ginkgo.Label(icttLabel, nativeTokenHomeLabel, erc20TokenRemoteLabel, multiHopLabel), + func() { + icttFlows.NativeTokenHomeERC20TokenRemoteMultiHop(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer an ERC20 token to a native token", + ginkgo.Label(icttLabel, erc20TokenHomeLabel, nativeTokenRemoteLabel), + func() { + icttFlows.ERC20TokenHomeNativeTokenRemote(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer a native token with ERC20TokenHome multi-hop", + ginkgo.Label(icttLabel, erc20TokenHomeLabel, nativeTokenRemoteLabel, multiHopLabel), + func() { + icttFlows.ERC20TokenHomeNativeTokenRemoteMultiHop(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer a native token to a native token multi-hop", + ginkgo.Label(icttLabel, nativeTokenHomeLabel, nativeTokenRemoteLabel, multiHopLabel), + func() { + icttFlows.NativeTokenHomeNativeTokenRemoteMultiHop(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transfer an ERC20 token using sendAndCall", + ginkgo.Label(icttLabel, erc20TokenHomeLabel, erc20TokenRemoteLabel, sendAndCallLabel), + func() { + icttFlows.ERC20TokenHomeERC20TokenRemoteSendAndCall(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Registration and collateral checks", + ginkgo.Label(icttLabel, erc20TokenHomeLabel, nativeTokenRemoteLabel, registrationLabel), + func() { + icttFlows.RegistrationAndCollateralCheck(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Transparent proxy upgrade", + ginkgo.Label(icttLabel, erc20TokenHomeLabel, erc20TokenRemoteLabel, upgradabilityLabel), + func() { + icttFlows.TransparentUpgradeableProxy(LocalNetworkInstance, TeleporterInfo) + }) +}) diff --git a/icm-contracts/tests/suites/teleporter/teleporter_suite_test.go b/icm-contracts/tests/suites/teleporter/teleporter_suite_test.go new file mode 100644 index 000000000..3cae8e81f --- /dev/null +++ b/icm-contracts/tests/suites/teleporter/teleporter_suite_test.go @@ -0,0 +1,247 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package teleporter_test + +import ( + "context" + "flag" + "os" + "testing" + "time" + + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/units" + teleporterFlows "github.com/ava-labs/icm-services/icm-contracts/tests/flows/teleporter" + registryFlows "github.com/ava-labs/icm-services/icm-contracts/tests/flows/teleporter/registry" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + deploymentUtils "github.com/ava-labs/icm-services/icm-contracts/utils/deployment-utils" + "github.com/ava-labs/libevm/log" + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + teleporterByteCodeFile = "./out/TeleporterMessenger.sol/TeleporterMessenger.json" + warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" + + teleporterMessengerLabel = "TeleporterMessenger" + upgradabilityLabel = "upgradability" + utilsLabel = "utils" + + teleporterRegistryAddressFile = "TeleporterRegistryAddress.json" + validatorAddressesFile = "ValidatorAddresses.json" +) + +var ( + LocalNetworkInstance *network.LocalNetwork + TeleporterInfo utils.TeleporterTestInfo + e2eFlags *e2e.FlagVars +) + +func TestMain(m *testing.M) { + e2eFlags = e2e.RegisterFlags() + flag.Parse() + os.Exit(m.Run()) +} + +func TestTeleporter(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + + RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "Teleporter e2e test") +} + +// Define the Teleporter before and after suite functions. +var _ = ginkgo.BeforeSuite(func() { + // Generate the Teleporter deployment values + teleporterDeployerTransaction, + teleporterDeployedBytecode, + teleporterDeployerAddress, + teleporterContractAddress, + err := deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + Expect(err).Should(BeNil()) + + // Create the local network instance + ctx, cancel := context.WithTimeout(context.Background(), 240*2*time.Second) + defer cancel() + + LocalNetworkInstance = network.NewLocalNetwork( + ctx, + "teleporter-test-local-network", + warpGenesisTemplateFile, + []network.L1Spec{ + { + Name: "A", + EVMChainID: 12345, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 5, + RequirePrimaryNetworkSigners: true, + }, + { + Name: "B", + EVMChainID: 54321, + TeleporterContractAddress: teleporterContractAddress, + TeleporterDeployedBytecode: teleporterDeployedBytecode, + TeleporterDeployerAddress: teleporterDeployerAddress, + NodeCount: 5, + RequirePrimaryNetworkSigners: true, + }, + }, + 2, + 2, + e2eFlags, + ) + TeleporterInfo = utils.NewTeleporterTestInfo(LocalNetworkInstance.GetAllL1Infos()) + log.Info("Started local network") + + // Only need to deploy Teleporter on the C-Chain since it is included in the genesis of the l1 chains. + _, fundedKey := LocalNetworkInstance.GetFundedAccountInfo() + if e2eFlags.NetworkDir() == "" { + TeleporterInfo.DeployTeleporterMessenger( + ctx, + LocalNetworkInstance.GetPrimaryNetworkInfo(), + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + balance := 100 * units.Avax + for _, subnet := range LocalNetworkInstance.GetL1Infos() { + // Choose weights such that we can test validator churn + LocalNetworkInstance.ConvertSubnet( + ctx, + subnet, + utils.PoAValidatorManager, + []uint64{units.Schmeckle, units.Schmeckle, units.Schmeckle, units.Schmeckle, units.Schmeckle}, + []uint64{balance, balance, balance, balance, balance}, + fundedKey, + false, + ) + } + + for _, l1 := range LocalNetworkInstance.GetAllL1Infos() { + TeleporterInfo.SetTeleporter(teleporterContractAddress, l1) + TeleporterInfo.InitializeBlockchainID(l1, fundedKey) + TeleporterInfo.DeployTeleporterRegistry(l1, fundedKey) + } + + // Save the Teleporter registry address and validator addresses to files + utils.SaveRegistyAddress(TeleporterInfo, teleporterRegistryAddressFile) + + LocalNetworkInstance.SaveValidatorAddress(validatorAddressesFile) + } else { + // Read the Teleporter registry address from the file + utils.SetTeleporterInfoFromFile( + teleporterRegistryAddressFile, + teleporterContractAddress, + TeleporterInfo, + LocalNetworkInstance.GetAllL1Infos(), + ) + + // Read the validator addresses from the file + LocalNetworkInstance.SetValidatorAddressFromFile(validatorAddressesFile) + } + + log.Info("Set up ginkgo before suite") +}) + +var _ = ginkgo.AfterSuite(func() { + LocalNetworkInstance.TearDownNetwork() + LocalNetworkInstance = nil +}) + +var _ = ginkgo.Describe("[Teleporter integration tests]", func() { + // Teleporter tests + ginkgo.It("Send a message from L1 A to L1 B, and one from B to A", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.BasicSendReceive(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Deliver to the wrong chain", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.DeliverToWrongChain(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Deliver to non-existent contract", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.DeliverToNonExistentContract(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Retry successful execution", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.RetrySuccessfulExecution(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Unallowed relayer", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.UnallowedRelayer(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Relay message twice", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.RelayMessageTwice(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Add additional fee amount", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.AddFeeAmount(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Send specific receipts", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.SendSpecificReceipts(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Insufficient gas", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.InsufficientGas(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Resubmit altered message", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.ResubmitAlteredMessage(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Calculate Teleporter message IDs", + ginkgo.Label(utilsLabel), + func() { + teleporterFlows.CalculateMessageID(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Relayer modifies message", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.RelayerModifiesMessage(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Validator churn", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporterFlows.ValidatorChurn(LocalNetworkInstance, TeleporterInfo) + }) + + // Teleporter Registry tests + ginkgo.It("Teleporter registry", + ginkgo.Label(upgradabilityLabel), + func() { + registryFlows.TeleporterRegistry(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Check upgrade access", + ginkgo.Label(upgradabilityLabel), + func() { + registryFlows.CheckUpgradeAccess(LocalNetworkInstance, TeleporterInfo) + }) + ginkgo.It("Pause and Unpause Teleporter", + ginkgo.Label(upgradabilityLabel), + func() { + registryFlows.PauseTeleporter(LocalNetworkInstance, TeleporterInfo) + }) +}) diff --git a/icm-contracts/tests/suites/validator-manager/validator_manager_suite_test.go b/icm-contracts/tests/suites/validator-manager/validator_manager_suite_test.go new file mode 100644 index 000000000..6fe4e27bb --- /dev/null +++ b/icm-contracts/tests/suites/validator-manager/validator_manager_suite_test.go @@ -0,0 +1,100 @@ +package validator_manager_test + +import ( + "context" + "flag" + "os" + "testing" + "time" + + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + validatorManagerFlows "github.com/ava-labs/icm-services/icm-contracts/tests/flows/validator-manager" + localnetwork "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/libevm/log" + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + warpGenesisTemplateFile = "./tests/utils/warp-genesis-template.json" + validatorManagerLabel = "ValidatorManager" +) + +var ( + LocalNetworkInstance *localnetwork.LocalNetwork + e2eFlags *e2e.FlagVars +) + +func TestMain(m *testing.M) { + e2eFlags = e2e.RegisterFlags() + flag.Parse() + os.Exit(m.Run()) +} + +func TestValidatorManager(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + + RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "Validator Manager e2e test") +} + +// Define the before and after suite functions. +var _ = ginkgo.BeforeEach(func() { + // Create the local network instance + ctx, cancel := context.WithTimeout(context.Background(), 240*time.Second) + defer cancel() + LocalNetworkInstance = localnetwork.NewLocalNetwork( + ctx, + "validator-manager-test-local-network", + warpGenesisTemplateFile, + []localnetwork.L1Spec{ + { + Name: "A", + EVMChainID: 12345, + NodeCount: 2, + RequirePrimaryNetworkSigners: true, + }, + { + Name: "B", + EVMChainID: 54321, + NodeCount: 2, + RequirePrimaryNetworkSigners: true, + }, + }, + 2, + 2, + e2eFlags, + ) + log.Info("Started local network") +}) + +var _ = ginkgo.AfterEach(func() { + LocalNetworkInstance.TearDownNetwork() + LocalNetworkInstance = nil +}) + +var _ = ginkgo.Describe("[Validator manager integration tests]", func() { + // Validator Manager tests + ginkgo.It("Native token staking manager", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.NativeTokenStakingManager(LocalNetworkInstance) + }) + ginkgo.It("ERC20 token staking manager", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.ERC20TokenStakingManager(LocalNetworkInstance) + }) + ginkgo.It("PoA migration to PoS", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.PoAMigrationToPoS(LocalNetworkInstance) + }) + ginkgo.It("Delegate disable validator", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManagerFlows.RemoveDelegatorInactiveValidator(LocalNetworkInstance) + }) +}) diff --git a/icm-contracts/tests/utils/chain.go b/icm-contracts/tests/utils/chain.go new file mode 100644 index 000000000..b5c6df8cb --- /dev/null +++ b/icm-contracts/tests/utils/chain.go @@ -0,0 +1,718 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "encoding/json" + "errors" + "fmt" + goLog "log" + "math/big" + "os" + "slices" + "strconv" + "strings" + "time" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + nativeMinter "github.com/ava-labs/icm-services/abi-bindings/go/subnet-evm/INativeMinter" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + gasUtils "github.com/ava-labs/icm-services/icm-contracts/utils/gas-utils" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/eth/tracers" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/ethclient" + "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + subnetEvmUtils "github.com/ava-labs/subnet-evm/tests/utils" + . "github.com/onsi/gomega" +) + +const ( + CChainPathSpecifier = "C" +) + +var NativeTransferGas uint64 = 21_000 + +var WarpEnabledChainConfig = map[string]any{ + "log-level": "debug", + "warp-api-enabled": true, + "local-txs-enabled": true, + "eth-apis": []string{ + "eth", + "eth-filter", + "net", + "admin", + "web3", + "internal-eth", + "internal-blockchain", + "internal-transaction", + "internal-debug", + "internal-account", + "internal-personal", + "debug", + "debug-tracer", + "debug-file-tracer", + "debug-handler", + }, +} + +type Node struct { + NodeID ids.NodeID + NodePoP *signer.ProofOfPossession + Weight uint64 +} + +// +// URL utils +// + +func HttpToWebsocketURI(uri string, blockchainID string) string { + return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +func HttpToRPCURI(uri string, blockchainID string) string { + return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +// Get the host and port from a URI. The URI should be in the format http://host:port or https://host:port +func GetURIHostAndPort(uri string) (string, uint32, error) { + // At a minimum uri should have http:// of 7 characters + Expect(len(uri)).Should(BeNumerically(">", 7)) + if uri[:7] == "http://" { + uri = uri[7:] + } else if uri[:8] == "https://" { + uri = uri[8:] + } else { + return "", 0, fmt.Errorf("invalid uri: %s", uri) + } + + // Split the uri into host and port + hostAndPort := strings.Split(uri, ":") + Expect(len(hostAndPort)).Should(Equal(2)) + + // Parse the port + port, err := strconv.ParseUint(hostAndPort[1], 10, 32) + if err != nil { + return "", 0, fmt.Errorf("failed to parse port: %w", err) + } + + return hostAndPort[0], uint32(port), nil +} + +// +// Transaction utils +// + +func CreateNativeTransferTransaction( + ctx context.Context, + l1Info interfaces.L1TestInfo, + fromKey *ecdsa.PrivateKey, + recipient common.Address, + amount *big.Int, +) *types.Transaction { + fromAddress := crypto.PubkeyToAddress(fromKey.PublicKey) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, l1Info, fromAddress) + + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: l1Info.EVMChainID, + Nonce: nonce, + To: &recipient, + Gas: NativeTransferGas, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: amount, + }) + + return SignTransaction(tx, fromKey, l1Info.EVMChainID) +} + +func SendNativeTransfer( + ctx context.Context, + l1Info interfaces.L1TestInfo, + fromKey *ecdsa.PrivateKey, + recipient common.Address, + amount *big.Int, +) *types.Receipt { + tx := CreateNativeTransferTransaction(ctx, l1Info, fromKey, recipient, amount) + return SendTransactionAndWaitForSuccess(ctx, l1Info, tx) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals success. +func sendAndWaitForTransaction( + ctx context.Context, + l1Info interfaces.L1TestInfo, + tx *types.Transaction, + success bool, +) *types.Receipt { + err := l1Info.RPCClient.SendTransaction(ctx, tx) + Expect(err).Should(BeNil()) + + return waitForTransaction(ctx, l1Info, tx.Hash(), success) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals false. +func SendTransactionAndWaitForFailure( + ctx context.Context, + l1Info interfaces.L1TestInfo, + tx *types.Transaction, +) *types.Receipt { + return sendAndWaitForTransaction(ctx, l1Info, tx, false) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals true. +func SendTransactionAndWaitForSuccess( + ctx context.Context, + l1Info interfaces.L1TestInfo, + tx *types.Transaction, +) *types.Receipt { + return sendAndWaitForTransaction(ctx, l1Info, tx, true) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals true. +func WaitForTransactionSuccess( + ctx context.Context, + l1Info interfaces.L1TestInfo, + txHash common.Hash, +) *types.Receipt { + return waitForTransaction(ctx, l1Info, txHash, true) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals false. +func WaitForTransactionFailure( + ctx context.Context, + l1Info interfaces.L1TestInfo, + txHash common.Hash, +) *types.Receipt { + return waitForTransaction(ctx, l1Info, txHash, false) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals success. +func waitForTransaction( + ctx context.Context, + l1Info interfaces.L1TestInfo, + txHash common.Hash, + success bool, +) *types.Receipt { + cctx, cancel := context.WithTimeout(ctx, 20*time.Second) + defer cancel() + + receipt, err := WaitMined(cctx, l1Info.RPCClient, txHash) + Expect(err).Should(BeNil()) + + if success { + if receipt.Status == types.ReceiptStatusFailed { + TraceTransactionAndExit(ctx, l1Info.RPCClient, receipt.TxHash) + } + } else { + Expect(receipt.Status).Should(Equal(types.ReceiptStatusFailed)) + } + return receipt +} + +// Polls for a transaction receipt of the given txHash on each queryTicker tick until +// either a transaction receipt returned, or the context is cancelled or expired. +func waitForTransactionReceipt( + cctx context.Context, + rpcClient ethclient.Client, + txHash common.Hash, +) (*types.Receipt, error) { + queryTicker := time.NewTicker(200 * time.Millisecond) + defer queryTicker.Stop() + for { + receipt, err := rpcClient.TransactionReceipt(cctx, txHash) + if err == nil { + return receipt, nil + } + + if errors.Is(err, ethereum.NotFound) { + log.Debug("Transaction not yet mined") + } else { + log.Error("Receipt retrieval failed", "err", err) + return nil, err + } + + // Wait for the next round. + select { + case <-cctx.Done(): + return nil, cctx.Err() + case <-queryTicker.C: + } + } +} + +// Signs a transaction using the provided key for the specified chainID +func SignTransaction(tx *types.Transaction, key *ecdsa.PrivateKey, chainID *big.Int) *types.Transaction { + txSigner := types.LatestSignerForChainID(chainID) + signedTx, err := types.SignTx(tx, txSigner, key) + Expect(err).Should(BeNil()) + + return signedTx +} + +// Returns the gasFeeCap, gasTipCap, and nonce the be used when constructing a transaction from fundedAddress +func CalculateTxParams( + ctx context.Context, + l1Info interfaces.L1TestInfo, + fundedAddress common.Address, +) (*big.Int, *big.Int, uint64) { + baseFee, err := l1Info.RPCClient.EstimateBaseFee(ctx) + Expect(err).Should(BeNil()) + + gasTipCap, err := l1Info.RPCClient.SuggestGasTipCap(ctx) + Expect(err).Should(BeNil()) + + nonce, err := l1Info.RPCClient.NonceAt(ctx, fundedAddress, nil) + Expect(err).Should(BeNil()) + + gasFeeCap := baseFee.Mul(baseFee, big.NewInt(gasUtils.BaseFeeFactor)) + gasFeeCap.Add(gasFeeCap, big.NewInt(gasUtils.MaxPriorityFeePerGas)) + + return gasFeeCap, gasTipCap, nonce +} + +// Gomega will print the transaction trace and exit +func TraceTransactionAndExit(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) { + Expect(TraceTransaction(ctx, rpcClient, txHash)).Should(Equal("")) +} + +func TraceTransaction(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) string { + var result interface{} + ct := "callTracer" + err := rpcClient.Client().Call(&result, "debug_traceTransaction", txHash.String(), tracers.TraceConfig{Tracer: &ct}) + Expect(err).Should(BeNil()) + + jsonStr, err := json.Marshal(result) + Expect(err).Should(BeNil()) + + return string(jsonStr) +} + +// +// Block utils +// + +// WaitMined waits for tx to be mined on the blockchain. +// It stops waiting when the context is canceled. +// Takes a tx hash instead of the full tx in the subnet-evm version of this function. +// Copied and modified from https://github.com/ava-labs/subnet-evm/blob/v0.6.0-fuji/accounts/abi/bind/util.go#L42 +func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) (*types.Receipt, error) { + now := time.Now() + receipt, err := waitForTransactionReceipt(ctx, rpcClient, txHash) + if err != nil { + return nil, err + } + since := time.Since(now) + goLog.Println("Transaction mined", "txHash", txHash.Hex(), "duration", since) + + // Check that the block height endpoint returns a block height as high as the block number that the transaction was + // included in. This is to workaround the issue where multiple nodes behind a public RPC endpoint see + // transactions/blocks at different points in time. Ideally, all nodes in the network should have seen this block + // and transaction before returning from WaitMined. The block height endpoint of public RPC endpoints is + // configured to return the lowest value currently returned by any node behind the load balancer, so waiting for + // it to be at least as high as the block height specified in the receipt should provide a relatively strong + // indication that the transaction has been seen widely throughout the network. + err = waitForBlockHeight(ctx, rpcClient, receipt.BlockNumber.Uint64()) + if err != nil { + return nil, err + } + + return receipt, nil +} + +// Polls for the eth_blockNumber endpoint for the latest blockheight on each queryTicker tick until +// either the returned height is greater than or equal to the expectedBlockNumber, or the context +// is cancelled or expired. +func waitForBlockHeight( + cctx context.Context, + rpcClient ethclient.Client, + expectedBlockNumber uint64, +) error { + queryTicker := time.NewTicker(2 * time.Second) + defer queryTicker.Stop() + for { + currentBlockNumber, err := rpcClient.BlockNumber(cctx) + if err != nil { + return err + } + + if currentBlockNumber >= expectedBlockNumber { + return nil + } else { + log.Info("Waiting for block height where transaction was included", + "blockNumber", expectedBlockNumber) + } + + // Wait for the next round. + select { + case <-cctx.Done(): + return cctx.Err() + case <-queryTicker.C: + } + } +} + +// +// Log utils +// + +// Returns the first log in 'logs' that is successfully parsed by 'parser' +// Errors and prints a trace of the transaction if no log is found. +func GetEventFromLogsOrTrace[T any]( + ctx context.Context, + receipt *types.Receipt, + l1Info interfaces.L1TestInfo, + parser func(log types.Log) (T, error), +) T { + log, err := GetEventFromLogs(receipt.Logs, parser) + if err != nil { + TraceTransactionAndExit(ctx, l1Info.RPCClient, receipt.TxHash) + } + return log +} + +// Returns the first log in 'logs' that is successfully parsed by 'parser' +func GetEventFromLogs[T any](logs []*types.Log, parser func(log types.Log) (T, error)) (T, error) { + for _, log := range logs { + event, err := parser(*log) + if err == nil { + return event, nil + } + } + return *new(T), fmt.Errorf("failed to find %T event in receipt logs", *new(T)) +} + +// +// Account utils +// + +func PrivateKeyToAddress(k *ecdsa.PrivateKey) common.Address { + return crypto.PubkeyToAddress(k.PublicKey) +} + +// Throws a Gomega error if there is a mismatch +func CheckBalance(ctx context.Context, addr common.Address, expectedBalance *big.Int, rpcClient ethclient.Client) { + bal, err := rpcClient.BalanceAt(ctx, addr, nil) + Expect(err).Should(BeNil()) + ExpectBigEqual(bal, expectedBalance) +} + +// +// Big int utils +// + +func ExpectBigEqual(v1 *big.Int, v2 *big.Int) { + // Compare strings, so gomega will print the numbers if they differ + Expect(v1.String()).Should(Equal(v2.String())) +} + +func BigIntSub(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Sub(v1, v2) +} + +func BigIntMul(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Mul(v1, v2) +} + +// +// Network utils +// + +func GetPChainInfo(cChainInfo interfaces.L1TestInfo) interfaces.L1TestInfo { + pChainBlockchainID, err := info.NewClient(cChainInfo.NodeURIs[0]).GetBlockchainID(context.Background(), "P") + Expect(err).Should(BeNil()) + return interfaces.L1TestInfo{ + BlockchainID: pChainBlockchainID, + SubnetID: ids.Empty, + } +} + +type ChainConfigMap map[string]string + +// Sets the chain config in customChainConfigs for the specified L! +func (m ChainConfigMap) Add(l1 interfaces.L1TestInfo, chainConfig string) { + if l1.SubnetID == constants.PrimaryNetworkID { + m[CChainPathSpecifier] = chainConfig + } else { + m[l1.BlockchainID.String()] = chainConfig + } +} + +func GetChainConfigWithOffChainMessages(offChainMessages []avalancheWarp.UnsignedMessage) string { + // Convert messages to hex + hexOffChainMessages := []string{} + for _, message := range offChainMessages { + hexOffChainMessages = append(hexOffChainMessages, hexutil.Encode(message.Bytes())) + } + + chainConfig := WarpEnabledChainConfig + chainConfig["warp-off-chain-messages"] = hexOffChainMessages + + // Marshal the map to JSON + offChainMessageJson, err := tmpnet.DefaultJSONMarshal(chainConfig) + Expect(err).Should(BeNil()) + + return string(offChainMessageJson) +} + +// read in the template file, make the substitutions declared at the beginning +// of the function, write out the instantiation to a temp file, and then return +// the path to that temp file. +func InstantiateGenesisTemplate( + templateFileName string, + chainID uint64, + teleporterContractAddress common.Address, + teleporterDeployedBytecode string, + teleporterDeployerAddress common.Address, + requirePrimaryNetworkSigners bool, +) string { + if teleporterContractAddress.Big().Cmp(big.NewInt(0)) == 0 { + teleporterContractAddress = common.HexToAddress("0xffffffffffffffffffffffffffffffffffffffff") + } + if teleporterDeployerAddress.Big().Cmp(big.NewInt(0)) == 0 { + teleporterDeployerAddress = common.HexToAddress("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + } + if teleporterDeployedBytecode == "" { + teleporterDeployedBytecode = "0x00" + } + + substitutions := []struct { + Target string + Value string + }{ + { + "", + strconv.FormatUint(chainID, 10), + }, + { + "", + teleporterContractAddress.Hex(), + }, + { + "", + teleporterDeployedBytecode, + }, + { + "", + teleporterDeployerAddress.Hex(), + }, + { + "", + strconv.FormatBool(requirePrimaryNetworkSigners), + }, + } + + templateFileBytes, err := os.ReadFile(templateFileName) + Expect(err).Should(BeNil()) + + l1GenesisFile, err := os.CreateTemp(os.TempDir(), "") + Expect(err).Should(BeNil()) + + defer l1GenesisFile.Close() + + var replaced string = string(templateFileBytes[:]) + for _, s := range substitutions { + replaced = strings.ReplaceAll(replaced, s.Target, s.Value) + } + + l1GenesisFile.WriteString(replaced) + + return l1GenesisFile.Name() +} + +// Native minter utils +// + +// Funded key must have admin access to set new admin. +func AddNativeMinterAdmin( + ctx context.Context, + l1 interfaces.L1TestInfo, + fundedKey *ecdsa.PrivateKey, + address common.Address, +) { + nativeMinterPrecompile, err := nativeMinter.NewINativeMinter(nativeminter.ContractAddress, l1.RPCClient) + Expect(err).Should(BeNil()) + + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := nativeMinterPrecompile.SetAdmin(opts, address) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} + +// Blocks until all validators specified in nodeURIs have reached the specified block height +func WaitForAllValidatorsToAcceptBlock(ctx context.Context, nodeURIs []string, blockchainID ids.ID, height uint64) { + cctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + for i, uri := range nodeURIs { + chainAWSURI := HttpToWebsocketURI(uri, blockchainID.String()) + log.Debug("Creating ethclient for blockchain", "blockchainID", blockchainID.String(), "wsURI", chainAWSURI) + client, err := ethclient.Dial(chainAWSURI) + Expect(err).Should(BeNil()) + defer client.Close() + + // Loop until each node has advanced to >= the height of the block that emitted the warp log + for { + block, err := client.BlockByNumber(cctx, nil) + Expect(err).Should(BeNil()) + if block.NumberU64() >= height { + log.Debug("Client accepted the block containing SendWarpMessage", "client", i, "height", block.NumberU64()) + break + } + } + } +} + +func ExtractWarpMessageFromLog( + ctx context.Context, + sourceReceipt *types.Receipt, + source interfaces.L1TestInfo, +) *avalancheWarp.UnsignedMessage { + log.Info("Fetching relevant warp logs from the newly produced block") + logs, err := source.RPCClient.FilterLogs(ctx, ethereum.FilterQuery{ + BlockHash: &sourceReceipt.BlockHash, + Addresses: []common.Address{warp.Module.Address}, + }) + Expect(err).Should(BeNil()) + Expect(len(logs)).Should(Equal(1)) + + // Check for relevant warp log from subscription and ensure that it matches + // the log extracted from the last block. + txLog := logs[0] + log.Info("Parsing logData as unsigned warp message") + unsignedMsg, err := warp.UnpackSendWarpEventDataToMessage(txLog.Data) + Expect(err).Should(BeNil()) + return unsignedMsg +} + +func ConstructSignedWarpMessage( + ctx context.Context, + sourceReceipt *types.Receipt, + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + justification []byte, + signatureAggregator *SignatureAggregator, +) *avalancheWarp.Message { + unsignedMsg := ExtractWarpMessageFromLog(ctx, sourceReceipt, source) + + // Loop over each client on source chain to ensure they all have time to accept the block. + // Note: if we did not confirm this here, the next stage could be racy since it assumes every node + // has accepted the block. + WaitForAllValidatorsToAcceptBlock(ctx, source.NodeURIs, source.BlockchainID, sourceReceipt.BlockNumber.Uint64()) + + // Get the aggregate signature for the Warp message + log.Info("Fetching aggregate signature from the source chain validators") + return GetSignedMessage(source, destination, unsignedMsg, justification, signatureAggregator) +} + +func GetSignedMessage( + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + unsignedWarpMessage *avalancheWarp.UnsignedMessage, + justification []byte, + signatureAggregator *SignatureAggregator, +) *avalancheWarp.Message { + signingSubnetID := source.SubnetID + if source.SubnetID == constants.PrimaryNetworkID && !destination.RequirePrimaryNetworkSigners { + signingSubnetID = destination.SubnetID + } + + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedWarpMessage, + justification, + signingSubnetID, + warp.WarpDefaultQuorumNumerator, + ) + Expect(err).Should(BeNil()) + + return signedWarpMessage +} + +func SetupProposerVM(ctx context.Context, fundedKey *ecdsa.PrivateKey, network *tmpnet.Network, SubnetID ids.ID) { + l1Details := network.Subnets[slices.IndexFunc( + network.Subnets, + func(s *tmpnet.Subnet) bool { return s.SubnetID == SubnetID }, + )] + + chainID := l1Details.Chains[0].ChainID + + node, err := network.GetNode(l1Details.ValidatorIDs[0]) + Expect(err).Should(BeNil()) + uri := HttpToWebsocketURI(node.URI, chainID.String()) + + client, err := ethclient.Dial(uri) + Expect(err).Should(BeNil()) + chainIDInt, err := client.ChainID(ctx) + Expect(err).Should(BeNil()) + + err = subnetEvmUtils.IssueTxsToActivateProposerVMFork(ctx, chainIDInt, fundedKey, client) + Expect(err).Should(BeNil()) +} + +// Adapted from [subnetEvmUtils.IssueTxsToActivateProposerVMFork] +// Since those transactions with hardcoded low caps don't get included successfully +// post Fortuna +func IssueTxsToAdvanceChain( + ctx context.Context, + chainID *big.Int, + fundedKey *ecdsa.PrivateKey, + client ethclient.Client, + numTriggerTxs int, +) error { + addr := crypto.PubkeyToAddress(fundedKey.PublicKey) + nonce, err := client.NonceAt(ctx, addr, nil) + Expect(err).Should(BeNil()) + + newHeads := make(chan *types.Header, 1) + sub, err := client.SubscribeNewHead(ctx, newHeads) + if err != nil { + return err + } + defer sub.Unsubscribe() + + to := common.HexToAddress(string(common.Big1.Bytes())) + gasFeeCap := big.NewInt(0).SetUint64(225_000_000_000) + + txSigner := types.LatestSignerForChainID(chainID) + for i := 0; i < numTriggerTxs; i++ { + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainID, + Nonce: nonce, + To: &to, + Gas: NativeTransferGas, + GasFeeCap: gasFeeCap, + GasTipCap: common.Big0, + Value: common.Big1, + }) + triggerTx, err := types.SignTx(tx, txSigner, fundedKey) + if err != nil { + return err + } + if err := client.SendTransaction(ctx, triggerTx); err != nil { + return err + } + <-newHeads // wait for block to be accepted + nonce++ + } + log.Info( + "Built required number of blocks", + "txCount", numTriggerTxs, + ) + return nil +} diff --git a/icm-contracts/tests/utils/constants.go b/icm-contracts/tests/utils/constants.go new file mode 100644 index 000000000..3d18fb0c8 --- /dev/null +++ b/icm-contracts/tests/utils/constants.go @@ -0,0 +1,8 @@ +package utils + +import "math/big" + +var ( + DefaultERC20RequiredGas = big.NewInt(100_000) + DefaultNativeTokenRequiredGas = big.NewInt(135_000) +) diff --git a/icm-contracts/tests/utils/erc20.go b/icm-contracts/tests/utils/erc20.go new file mode 100644 index 000000000..43b8ed987 --- /dev/null +++ b/icm-contracts/tests/utils/erc20.go @@ -0,0 +1,61 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "math/big" + + exampleerc20 "github.com/ava-labs/icm-services/abi-bindings/go/mocks/ExampleERC20" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +var ( + ExpectedExampleERC20DeployerBalance = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e10)) +) + +func DeployExampleERC20( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + source interfaces.L1TestInfo, +) (common.Address, *exampleerc20.ExampleERC20) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + + // Deploy Mock ERC20 contract + address, tx, token, err := exampleerc20.DeployExampleERC20(opts, source.RPCClient) + Expect(err).Should(BeNil()) + log.Info("Deployed Mock ERC20 contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, source, tx.Hash()) + + // Check that the deployer has the expected initial balance + senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) + balance, err := token.BalanceOf(&bind.CallOpts{}, senderAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(ExpectedExampleERC20DeployerBalance)) + + return address, token +} + +func ERC20Approve( + ctx context.Context, + token *exampleerc20.ExampleERC20, + spender common.Address, + amount *big.Int, + source interfaces.L1TestInfo, + senderKey *ecdsa.PrivateKey, +) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := token.Approve(opts, spender, amount) + Expect(err).Should(BeNil()) + log.Info("Approved ERC20", "spender", spender.Hex(), "txHash", tx.Hash().Hex()) + + WaitForTransactionSuccess(ctx, source, tx.Hash()) +} diff --git a/icm-contracts/tests/utils/governance.go b/icm-contracts/tests/utils/governance.go new file mode 100644 index 000000000..a3f0804f8 --- /dev/null +++ b/icm-contracts/tests/utils/governance.go @@ -0,0 +1,108 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + validatorsetsig "github.com/ava-labs/icm-services/abi-bindings/go/governance/ValidatorSetSig" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func DeployValidatorSetSig( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + contractL1 interfaces.L1TestInfo, + validatorL1 interfaces.L1TestInfo, +) (common.Address, *validatorsetsig.ValidatorSetSig) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, contractL1.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, validatorSetSig, err := validatorsetsig.DeployValidatorSetSig( + opts, + contractL1.RPCClient, + validatorL1.BlockchainID, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, contractL1, tx.Hash()) + + return address, validatorSetSig +} + +// Returns Receipt for the transaction unlike TeleporterRegistry version since this is a non-teleporter case +// and we don't want to add the ValidatorSetSig ABI to the L1Info +func ExecuteValidatorSetSigCallAndVerify( + ctx context.Context, + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + validatorSetSigAddress common.Address, + senderKey *ecdsa.PrivateKey, + unsignedMessage *avalancheWarp.UnsignedMessage, + signatureAggregator *SignatureAggregator, + expectSuccess bool, +) *types.Receipt { + signedWarpMsg := GetSignedMessage(source, destination, unsignedMessage, nil, signatureAggregator) + log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) + + signedPredicateTx := CreateExecuteCallPredicateTransaction( + ctx, + signedWarpMsg, + validatorSetSigAddress, + senderKey, + destination, + ) + + // Wait for tx to be accepted and verify events emitted + if expectSuccess { + return SendTransactionAndWaitForSuccess(ctx, destination, signedPredicateTx) + } + return SendTransactionAndWaitForFailure(ctx, destination, signedPredicateTx) +} + +func InitOffChainMessageChainConfigValidatorSetSig( + networkID uint32, + l1 interfaces.L1TestInfo, + validatorSetSigAddress common.Address, + validatorSetSigMessages []validatorsetsig.ValidatorSetSigMessage, +) ([]avalancheWarp.UnsignedMessage, string) { + unsignedMessages := []avalancheWarp.UnsignedMessage{} + for _, message := range validatorSetSigMessages { + unsignedMessage := CreateOffChainValidatorSetSigMessage(networkID, l1, message) + unsignedMessages = append(unsignedMessages, *unsignedMessage) + log.Info("Adding validatorSetSig off-chain message to Warp chain config", + "messageID", unsignedMessage.ID(), + "blockchainID", l1.BlockchainID.String()) + } + return unsignedMessages, GetChainConfigWithOffChainMessages(unsignedMessages) +} + +// Creates an off-chain Warp message pointing to a function, contract and payload to be executed +// if the validator set signs this message +func CreateOffChainValidatorSetSigMessage( + networkID uint32, + l1 interfaces.L1TestInfo, + message validatorsetsig.ValidatorSetSigMessage, +) *avalancheWarp.UnsignedMessage { + sourceAddress := []byte{} + payloadBytes, err := message.Pack() + Expect(err).Should(BeNil()) + + addressedPayload, err := payload.NewAddressedCall(sourceAddress, payloadBytes) + Expect(err).Should(BeNil()) + + unsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + l1.BlockchainID, + addressedPayload.Bytes(), + ) + Expect(err).Should(BeNil()) + + return unsignedMessage +} diff --git a/icm-contracts/tests/utils/ictt.go b/icm-contracts/tests/utils/ictt.go new file mode 100644 index 000000000..07afd2a85 --- /dev/null +++ b/icm-contracts/tests/utils/ictt.go @@ -0,0 +1,1113 @@ +// Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package utils + +import ( + "context" + "crypto/ecdsa" + "math" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + nativetokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/NativeTokenHome" + tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/TokenHome" + erc20tokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/ERC20TokenRemote" + nativetokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/NativeTokenRemote" + tokenremote "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenRemote/TokenRemote" + wrappednativetoken "github.com/ava-labs/icm-services/abi-bindings/go/ictt/WrappedNativeToken" + exampleerc20 "github.com/ava-labs/icm-services/abi-bindings/go/ictt/mocks/ExampleERC20Decimals" + mockERC20SACR "github.com/ava-labs/icm-services/abi-bindings/go/ictt/mocks/MockERC20SendAndCallReceiver" + mockNSACR "github.com/ava-labs/icm-services/abi-bindings/go/ictt/mocks/MockNativeSendAndCallReceiver" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + + . "github.com/onsi/gomega" +) + +// Deployer keys set in the genesis file in order to determine the deployed address in advance. +// The deployed address is set as an admin for the Native Minter precompile. + +var nativeTokenRemoteDeployerKeys = []string{ + // Deployer address: 0x1337cfd2dCff6270615B90938aCB1efE79801704 + // NativeTokenRemote address: 0xAcB633F5B00099c7ec187eB00156c5cd9D854b5B + "aad7440febfc8f9d73a58c3cb1f1754779a566978f9ebffcd4f4698e9b043985", + + // Deployer address: 0xFcec6c0674037f99fa473de09609B4b6D8158863 + // NativeTokenRemote address: 0x962c62B01529ecc0561D85d3fe395921ddC3665B + "81e5e98c89023dabbe43e1081314eaae174330aae6b44c9d1371b6c0bb7ae74a", + + // Deployer address: 0x2e1533d976A675bCD6306deC3B05e9f73e6722Fb + // NativeTokenRemote address: 0x1549B96D9D97F435CA9b25000FEDE3A7e54C0bb9 + "5ded9cacaca7b88d6a3dc24641cfe41ef00186f98e7fa65135eac50fd5977f7a", + + // Deployer address: 0xA638b0a597dc0520e2f20E83cFbeBBCd45a79990 + // NativeTokenRemote address: 0x190110D1228EB2cDd36559b2215A572Dc8592C3d + "a6c530cb407778d10e1f70be6624aa57d0c724f6f9cb585e9744052d7f48ba19", + + // Deployer address: 0x787C079cB0d5A7AA1Cae95d991F76Dce771A432D + // NativeTokenRemote address: 0xf9EF017A764F265A1fD0975bfc200725E41d860E + "e95fa6fd1d2a6b02890b75062bed583ce6256c5b473b3323b93ac4cbf20dbe7a", + + // Deployer address: 0x741D536f5B07bcD43727CD8435389CA36aE5A4Ae + // NativeTokenRemote address: 0x4f3663be6d22B0F19F8617f1A9E9485aB0144Bff + "8a92f3f468ce5b0d99f9aaa55695f93e03dbbb6d5e3faba80f92a7876be740d6", + // Deployer address: 0xd466f12795BA59d0fef389c21fA63c287956fb18 + // NativeTokenRemote address: 0x463a6bE7a5098A5f06435c6c468adD338F15B93A + "ebb7f0cf71e0b6fd880326e5f5061b8456b0aef81901566cbe578b5024852ec9", +} + +var ( + nativeTokenRemoteDeployerKeyIndex = 0 +) + +const NativeTokenDecimals = 18 + +func DeployERC20TokenHome( + ctx context.Context, + teleporter TeleporterTestInfo, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + teleporterManager common.Address, + tokenAddress common.Address, + tokenHomeDecimals uint8, +) (common.Address, *erc20tokenhome.ERC20TokenHome) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + l1.EVMChainID, + ) + Expect(err).Should(BeNil()) + implAddress, tx, erc20TokenHome, err := erc20tokenhome.DeployERC20TokenHome( + opts, + l1.RPCClient, + teleporter.TeleporterRegistryAddress(l1), + teleporterManager, + teleporter.GetLatestTeleporterVersion(l1), + tokenAddress, + tokenHomeDecimals, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return implAddress, erc20TokenHome +} + +func DeployERC20TokenRemote( + ctx context.Context, + teleporter TeleporterTestInfo, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + teleporterManager common.Address, + tokenHomeBlockchainID ids.ID, + tokenHomeAddress common.Address, + tokenHomeDecimals uint8, + tokenName string, + tokenSymbol string, + tokenDecimals uint8, +) (common.Address, *erc20tokenremote.ERC20TokenRemote) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + l1.EVMChainID, + ) + Expect(err).Should(BeNil()) + implAddress, tx, erc20TokenRemote, err := erc20tokenremote.DeployERC20TokenRemote( + opts, + l1.RPCClient, + erc20tokenremote.TokenRemoteSettings{ + TeleporterRegistryAddress: teleporter.TeleporterRegistryAddress(l1), + TeleporterManager: teleporterManager, + MinTeleporterVersion: teleporter.GetLatestTeleporterVersion(l1), + TokenHomeBlockchainID: tokenHomeBlockchainID, + TokenHomeAddress: tokenHomeAddress, + TokenHomeDecimals: tokenHomeDecimals, + }, + tokenName, + tokenSymbol, + tokenDecimals, + ) + Expect(err).Should(BeNil()) + + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return implAddress, erc20TokenRemote +} + +func DeployNativeTokenRemote( + ctx context.Context, + teleporter TeleporterTestInfo, + l1 interfaces.L1TestInfo, + symbol string, + teleporterManager common.Address, + tokenHomeBlockchainID ids.ID, + tokenHomeAddress common.Address, + tokenHomeDecimals uint8, + initialReserveImbalance *big.Int, + burnedFeesReportingRewardPercentage *big.Int, +) (common.Address, *nativetokenremote.NativeTokenRemote) { + // The NativeTokenRemote needs a unique deployer key, whose nonce 0 is used to deploy the contract. + // The resulting contract address has been added to the genesis file as an admin for the Native Minter precompile. + Expect(nativeTokenRemoteDeployerKeyIndex).Should(BeNumerically("<", len(nativeTokenRemoteDeployerKeys))) + deployerKeyStr := nativeTokenRemoteDeployerKeys[nativeTokenRemoteDeployerKeyIndex] + deployerPK, err := crypto.HexToECDSA(deployerKeyStr) + Expect(err).Should(BeNil()) + + opts, err := bind.NewKeyedTransactorWithChainID( + deployerPK, + l1.EVMChainID, + ) + Expect(err).Should(BeNil()) + + implAddress, tx, nativeTokenRemote, err := nativetokenremote.DeployNativeTokenRemote( + opts, + l1.RPCClient, + nativetokenremote.TokenRemoteSettings{ + TeleporterRegistryAddress: teleporter.TeleporterRegistryAddress(l1), + TeleporterManager: teleporterManager, + MinTeleporterVersion: teleporter.GetLatestTeleporterVersion(l1), + TokenHomeBlockchainID: tokenHomeBlockchainID, + TokenHomeAddress: tokenHomeAddress, + TokenHomeDecimals: tokenHomeDecimals, + }, + symbol, + initialReserveImbalance, + burnedFeesReportingRewardPercentage, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + // Increment to the next deployer key so that the next contract deployment succeeds + nativeTokenRemoteDeployerKeyIndex++ + + return implAddress, nativeTokenRemote +} + +func DeployNativeTokenHome( + ctx context.Context, + teleporter TeleporterTestInfo, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + teleporterManager common.Address, + tokenAddress common.Address, +) (common.Address, *nativetokenhome.NativeTokenHome) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + l1.EVMChainID, + ) + Expect(err).Should(BeNil()) + implAddress, tx, nativeTokenHome, err := nativetokenhome.DeployNativeTokenHome( + opts, + l1.RPCClient, + teleporter.TeleporterRegistryAddress(l1), + teleporterManager, + teleporter.GetLatestTeleporterVersion(l1), + tokenAddress, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return implAddress, nativeTokenHome +} + +func DeployWrappedNativeToken( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + tokenSymbol string, +) (common.Address, *wrappednativetoken.WrappedNativeToken) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + // Deploy mock WAVAX contract + address, tx, token, err := wrappednativetoken.DeployWrappedNativeToken( + opts, + l1.RPCClient, + tokenSymbol, + ) + Expect(err).Should(BeNil()) + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return address, token +} + +func DeployMockNativeSendAndCallReceiver( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, +) (common.Address, *mockNSACR.MockNativeSendAndCallReceiver) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + // Deploy MockNativeSendAndCallReceiver contract + address, tx, contract, err := mockNSACR.DeployMockNativeSendAndCallReceiver(opts, l1.RPCClient) + Expect(err).Should(BeNil()) + log.Info("Deployed MockNativeSendAndCallReceiver contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return address, contract +} + +func DeployMockERC20SendAndCallReceiver( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, +) (common.Address, *mockERC20SACR.MockERC20SendAndCallReceiver) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + // Deploy MockERC20SendAndCallReceiver contract + address, tx, contract, err := mockERC20SACR.DeployMockERC20SendAndCallReceiver(opts, l1.RPCClient) + Expect(err).Should(BeNil()) + log.Info("Deployed MockERC20SendAndCallReceiver contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return address, contract +} + +func DeployExampleERC20Decimals( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + tokenDecimals uint8, +) (common.Address, *exampleerc20.ExampleERC20Decimals) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + // Deploy Mock ERC20 contract + address, tx, token, err := exampleerc20.DeployExampleERC20Decimals(opts, l1.RPCClient, tokenDecimals) + Expect(err).Should(BeNil()) + log.Info("Deployed Mock ERC20 contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + // Check that the deployer has the expected initial balance + senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) + balance, err := token.BalanceOf(&bind.CallOpts{}, senderAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(ExpectedExampleERC20DeployerBalance)) + + return address, token +} + +func RegisterERC20TokenRemoteOnHome( + ctx context.Context, + teleporter TeleporterTestInfo, + homeL1 interfaces.L1TestInfo, + homeAddress common.Address, + remoteL1 interfaces.L1TestInfo, + remoteAddress common.Address, + fundedKey *ecdsa.PrivateKey, + signatureAggregator *SignatureAggregator, +) { + RegisterTokenRemoteOnHome( + ctx, + teleporter, + homeL1, + homeAddress, + remoteL1, + remoteAddress, + big.NewInt(0), + big.NewInt(1), + false, + fundedKey, + signatureAggregator, + ) +} + +func RegisterTokenRemoteOnHome( + ctx context.Context, + teleporter TeleporterTestInfo, + homeL1 interfaces.L1TestInfo, + homeAddress common.Address, + remoteL1 interfaces.L1TestInfo, + remoteAddress common.Address, + expectedInitialReserveBalance *big.Int, + expectedTokenMultiplier *big.Int, + expectedmultiplyOnRemote bool, + fundedKey *ecdsa.PrivateKey, + signatureAggregator *SignatureAggregator, +) *big.Int { + // Call the remote to send a register message to the home + tokenRemote, err := tokenremote.NewTokenRemote( + remoteAddress, + remoteL1.RPCClient, + ) + Expect(err).Should(BeNil()) + + // Deploy a new ERC20 token for testing registering with fees + feeTokenAddress, feeToken := DeployExampleERC20Decimals( + ctx, + fundedKey, + remoteL1, + 18, + ) + + // Approve the ERC20TokenHome to spend the tokens + feeAmount := big.NewInt(1e18) + ERC20DecimalsApprove( + ctx, + feeToken, + remoteAddress, + feeAmount, + remoteL1, + fundedKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, remoteL1.EVMChainID) + Expect(err).Should(BeNil()) + + sendRegisterTx, err := tokenRemote.RegisterWithHome( + opts, + tokenremote.TeleporterFeeInfo{ + FeeTokenAddress: feeTokenAddress, + Amount: feeAmount, + }, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, remoteL1, sendRegisterTx.Hash()) + + // Relay the register message to the home + receipt = teleporter.RelayTeleporterMessage( + ctx, + receipt, + remoteL1, + homeL1, + true, + fundedKey, + nil, + signatureAggregator, + ) + _, err = GetEventFromLogs( + receipt.Logs, + teleporter.TeleporterMessenger(homeL1).ParseMessageExecuted, + ) + if err != nil { + TraceTransactionAndExit(ctx, homeL1.RPCClient, receipt.TxHash) + } + + // Check that the remote registered event was emitted + tokenHome, err := tokenhome.NewTokenHome(homeAddress, homeL1.RPCClient) + Expect(err).Should(BeNil()) + registerEvent, err := GetEventFromLogs(receipt.Logs, tokenHome.ParseRemoteRegistered) + Expect(err).Should(BeNil()) + Expect(registerEvent.RemoteBlockchainID[:]).Should(Equal(remoteL1.BlockchainID[:])) + Expect(registerEvent.RemoteTokenTransferrerAddress).Should(Equal(remoteAddress)) + + // Based on the initial reserve balance of the TokenRemote instance, + // calculate the collateral amount of home tokens needed to collateralize the remote. + collateralNeeded := calculateCollateralNeeded( + expectedInitialReserveBalance, + expectedTokenMultiplier, + expectedmultiplyOnRemote, + ) + ExpectBigEqual(registerEvent.InitialCollateralNeeded, collateralNeeded) + + return collateralNeeded +} + +// AddCollateralToERC20TokenHome adds collateral to the ERC20TokenHome contract +// and verifies the collateral was added successfully. Any excess amount +// is returned to the caller. +func AddCollateralToERC20TokenHome( + ctx context.Context, + l1 interfaces.L1TestInfo, + erc20TokenHome *erc20tokenhome.ERC20TokenHome, + erc20TokenHomeAddress common.Address, + exampleERC20 *exampleerc20.ExampleERC20Decimals, + remoteBlockchainID ids.ID, + remoteAddress common.Address, + collateralAmount *big.Int, + senderKey *ecdsa.PrivateKey, +) { + // Approve the ERC20TokenHome to spend the collateral + ERC20DecimalsApprove( + ctx, + exampleERC20, + erc20TokenHomeAddress, + collateralAmount, + l1, + senderKey, + ) + + // Add collateral to the ERC20TokenHome + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := erc20TokenHome.AddCollateral( + opts, + remoteBlockchainID, + remoteAddress, + collateralAmount, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, erc20TokenHome.ParseCollateralAdded) + Expect(err).Should(BeNil()) + Expect(event.RemoteBlockchainID[:]).Should(Equal(remoteBlockchainID[:])) + Expect(event.RemoteTokenTransferrerAddress).Should(Equal(remoteAddress)) + + remoteSettings, err := erc20TokenHome.GetRemoteTokenTransferrerSettings( + &bind.CallOpts{}, + remoteBlockchainID, + remoteAddress) + Expect(err).Should(BeNil()) + if collateralAmount.Cmp(remoteSettings.CollateralNeeded) > 0 { + collateralAmount.Sub(collateralAmount, remoteSettings.CollateralNeeded) + } + ExpectBigEqual(event.Amount, collateralAmount) + ExpectBigEqual(event.Remaining, big.NewInt(0)) +} + +// AddCollateralToNativeTokenHome adds collateral to the NativeTokenHome contract +// and verifies the collateral was added successfully. Any excess amount +// is returned to the caller. +func AddCollateralToNativeTokenHome( + ctx context.Context, + l1 interfaces.L1TestInfo, + nativeTokenHome *nativetokenhome.NativeTokenHome, + nativeTokenHomeAddress common.Address, + remoteBlockchainID ids.ID, + remoteAddress common.Address, + collateralAmount *big.Int, + senderKey *ecdsa.PrivateKey, +) { + // Add collateral to the ERC20TokenHome + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = collateralAmount + + tx, err := nativeTokenHome.AddCollateral( + opts, + remoteBlockchainID, + remoteAddress, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, nativeTokenHome.ParseCollateralAdded) + Expect(err).Should(BeNil()) + Expect(event.RemoteBlockchainID[:]).Should(Equal(remoteBlockchainID[:])) + Expect(event.RemoteTokenTransferrerAddress).Should(Equal(remoteAddress)) + remoteSettings, err := nativeTokenHome.GetRemoteTokenTransferrerSettings( + &bind.CallOpts{}, + remoteBlockchainID, + remoteAddress) + Expect(err).Should(BeNil()) + if collateralAmount.Cmp(remoteSettings.CollateralNeeded) > 0 { + collateralAmount.Sub(collateralAmount, remoteSettings.CollateralNeeded) + } + ExpectBigEqual(event.Amount, collateralAmount) + ExpectBigEqual(event.Remaining, big.NewInt(0)) +} + +func SendERC20TokenHome( + ctx context.Context, + l1 interfaces.L1TestInfo, + erc20TokenHome *erc20tokenhome.ERC20TokenHome, + erc20TokenHomeAddress common.Address, + token *exampleerc20.ExampleERC20Decimals, + input erc20tokenhome.SendTokensInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, *big.Int) { + // Approve the ERC20TokenHome to spend the tokens + ERC20DecimalsApprove( + ctx, + token, + erc20TokenHomeAddress, + big.NewInt(0).Add(amount, input.PrimaryFee), + l1, + senderKey, + ) + + // Send the tokens and verify expected events + optsA, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := erc20TokenHome.Send( + optsA, + input, + amount, + ) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, erc20TokenHome.ParseTokensSent) + Expect(err).Should(BeNil()) + Expect(event.Sender).Should(Equal(crypto.PubkeyToAddress(senderKey.PublicKey))) + + // Compute the scaled amount + scaledAmount := GetScaledAmountFromERC20TokenHome( + erc20TokenHome, + input.DestinationBlockchainID, + input.DestinationTokenTransferrerAddress, + amount, + ) + ExpectBigEqual(event.Amount, scaledAmount) + + return receipt, event.Amount +} + +func SendNativeTokenHome( + ctx context.Context, + l1 interfaces.L1TestInfo, + nativeTokenHome *nativetokenhome.NativeTokenHome, + nativeTokenHomeAddress common.Address, + wrappedToken *wrappednativetoken.WrappedNativeToken, + input nativetokenhome.SendTokensInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, *big.Int) { + DepositAndApproveWrappedTokenForFees( + ctx, + l1, + wrappedToken, + input.PrimaryFee, + nativeTokenHomeAddress, + senderKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = amount + + tx, err := nativeTokenHome.Send( + opts, + input, + ) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, nativeTokenHome.ParseTokensSent) + Expect(err).Should(BeNil()) + Expect(event.Sender).Should(Equal(crypto.PubkeyToAddress(senderKey.PublicKey))) + + // Compute the scaled amount + scaledAmount := GetScaledAmountFromNativeTokenHome( + nativeTokenHome, + input.DestinationBlockchainID, + input.DestinationTokenTransferrerAddress, + amount, + ) + ExpectBigEqual(event.Amount, scaledAmount) + + return receipt, event.Amount +} + +func SendNativeTokenRemote( + ctx context.Context, + l1 interfaces.L1TestInfo, + nativeTokenRemote *nativetokenremote.NativeTokenRemote, + nativeTokenRemoteAddress common.Address, + input nativetokenremote.SendTokensInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, *big.Int) { + DepositAndApproveWrappedTokenForFees( + ctx, + l1, + nativeTokenRemote, + input.PrimaryFee, + nativeTokenRemoteAddress, + senderKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = amount + + tx, err := nativeTokenRemote.Send( + opts, + input, + ) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, nativeTokenRemote.ParseTokensSent) + Expect(err).Should(BeNil()) + Expect(event.Sender).Should(Equal(crypto.PubkeyToAddress(senderKey.PublicKey))) + ExpectBigEqual(event.Amount, amount) + + return receipt, event.Amount +} + +func SendERC20TokenRemote( + ctx context.Context, + l1 interfaces.L1TestInfo, + erc20TokenRemote *erc20tokenremote.ERC20TokenRemote, + erc20TokenRemoteAddress common.Address, + input erc20tokenremote.SendTokensInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, *big.Int) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := erc20TokenRemote.Approve( + opts, + erc20TokenRemoteAddress, + big.NewInt(0).Add(amount, input.PrimaryFee), + ) + Expect(err).Should(BeNil()) + + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + // Transfer the tokens back to l1 A + tx, err = erc20TokenRemote.Send( + opts, + input, + amount, + ) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, erc20TokenRemote.ParseTokensSent) + Expect(err).Should(BeNil()) + Expect(event.Sender).Should(Equal(crypto.PubkeyToAddress(senderKey.PublicKey))) + ExpectBigEqual(event.Amount, amount) + + return receipt, event.Amount +} + +func SendAndCallERC20TokenHome( + ctx context.Context, + l1 interfaces.L1TestInfo, + erc20TokenHome *erc20tokenhome.ERC20TokenHome, + erc20TokenHomeAddress common.Address, + exampleToken *exampleerc20.ExampleERC20Decimals, + input erc20tokenhome.SendAndCallInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, *big.Int) { + // Approve the ERC20TokenHome to spend the tokens + ERC20DecimalsApprove( + ctx, + exampleToken, + erc20TokenHomeAddress, + big.NewInt(0).Add(amount, input.PrimaryFee), + l1, + senderKey, + ) + + // Send the tokens and verify expected events + optsA, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := erc20TokenHome.SendAndCall( + optsA, + input, + amount, + ) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, erc20TokenHome.ParseTokensAndCallSent) + Expect(err).Should(BeNil()) + Expect(event.Input.RecipientContract).Should(Equal(input.RecipientContract)) + + // Computer the scaled amount + scaledAmount := GetScaledAmountFromERC20TokenHome( + erc20TokenHome, + input.DestinationBlockchainID, + input.DestinationTokenTransferrerAddress, + amount, + ) + ExpectBigEqual(event.Amount, scaledAmount) + + return receipt, event.Amount +} + +func SendAndCallNativeTokenHome( + ctx context.Context, + l1 interfaces.L1TestInfo, + nativeTokenHome *nativetokenhome.NativeTokenHome, + input nativetokenhome.SendAndCallInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, *big.Int) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = amount + + tx, err := nativeTokenHome.SendAndCall( + opts, + input, + ) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, nativeTokenHome.ParseTokensAndCallSent) + Expect(err).Should(BeNil()) + Expect(event.Input.RecipientContract).Should(Equal(input.RecipientContract)) + + // Compute the scaled amount + remoteSettings, err := nativeTokenHome.GetRemoteTokenTransferrerSettings( + &bind.CallOpts{}, + input.DestinationBlockchainID, + input.DestinationTokenTransferrerAddress) + Expect(err).Should(BeNil()) + + scaledAmount := ApplyTokenScaling( + remoteSettings.TokenMultiplier, + remoteSettings.MultiplyOnRemote, + amount, + ) + ExpectBigEqual(event.Amount, scaledAmount) + + return receipt, event.Amount +} + +func SendAndCallNativeTokenRemote( + ctx context.Context, + l1 interfaces.L1TestInfo, + nativeTokenRemote *nativetokenremote.NativeTokenRemote, + input nativetokenremote.SendAndCallInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, + tokenMultiplier *big.Int, + multiplyOnRemote bool, +) (*types.Receipt, *big.Int) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = amount + + tx, err := nativeTokenRemote.SendAndCall( + opts, + input, + ) + Expect(err).Should(BeNil()) + + transferredAmount := big.NewInt(0).Sub(amount, input.PrimaryFee) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, nativeTokenRemote.ParseTokensAndCallSent) + Expect(err).Should(BeNil()) + Expect(event.Input.RecipientContract).Should(Equal(input.RecipientContract)) + ExpectBigEqual(event.Amount, transferredAmount) + + return receipt, event.Amount +} + +func SendAndCallERC20TokenRemote( + ctx context.Context, + l1 interfaces.L1TestInfo, + erc20TokenRemote *erc20tokenremote.ERC20TokenRemote, + erc20TokenRemoteAddress common.Address, + input erc20tokenremote.SendAndCallInput, + amount *big.Int, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, *big.Int) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := erc20TokenRemote.Approve( + opts, + erc20TokenRemoteAddress, + big.NewInt(0).Add(amount, input.PrimaryFee), + ) + Expect(err).Should(BeNil()) + + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + // Transfer the tokens back to l1 A + tx, err = erc20TokenRemote.SendAndCall( + opts, + input, + amount, + ) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + event, err := GetEventFromLogs(receipt.Logs, erc20TokenRemote.ParseTokensAndCallSent) + Expect(err).Should(BeNil()) + Expect(event.Input.RecipientContract).Should(Equal(input.RecipientContract)) + ExpectBigEqual(event.Amount, amount) + + return receipt, event.Amount +} + +// Send a native token from fromTokenTransferrer to toTokenTransferrer via multi-hop through the C-Chain +// Requires that both fromTokenTransferrer and toTokenTransferrer are fully collateralized +// Requires that both fromTokenTransferrer and toTokenTransferrer have the same tokenMultiplier and multiplyOnRemote +// with respect to the original asset on the C-Chain +func SendNativeMultiHopAndVerify( + ctx context.Context, + teleporter TeleporterTestInfo, + sendingKey *ecdsa.PrivateKey, + recipientAddress common.Address, + fromL1 interfaces.L1TestInfo, + fromTokenTransferrer *nativetokenremote.NativeTokenRemote, + fromTokenTransferrerAddress common.Address, + toL1 interfaces.L1TestInfo, + toTokenTransferrer *nativetokenremote.NativeTokenRemote, + toTokenTransferrerAddress common.Address, + cChainInfo interfaces.L1TestInfo, + amount *big.Int, + secondaryFeeAmount *big.Int, + signatureAggregator *SignatureAggregator, +) { + input := nativetokenremote.SendTokensInput{ + DestinationBlockchainID: toL1.BlockchainID, + DestinationTokenTransferrerAddress: toTokenTransferrerAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: fromTokenTransferrerAddress, + PrimaryFee: big.NewInt(0), + SecondaryFee: secondaryFeeAmount, + RequiredGasLimit: DefaultNativeTokenRequiredGas, + MultiHopFallback: recipientAddress, + } + + // Send tokens through a multi-hop transfer + originReceipt, amount := SendNativeTokenRemote( + ctx, + fromL1, + fromTokenTransferrer, + fromTokenTransferrerAddress, + input, + amount, + sendingKey, + ) + + // Relay the first message back to the home chain, in this case C-Chain, + // which then performs the multi-hop transfer to the destination TokenRemote instance. + intermediateReceipt := teleporter.RelayTeleporterMessage( + ctx, + originReceipt, + fromL1, + cChainInfo, + true, + sendingKey, + nil, + signatureAggregator, + ) + + initialBalance, err := toL1.RPCClient.BalanceAt(ctx, recipientAddress, nil) + Expect(err).Should(BeNil()) + + // When we relay the above message to the home chain, a multi-hop transfer + // is performed to the destination TokenRemote instance. Parse for the send tokens event + // and relay to the destination TokenRemote instance. + teleporter.RelayTeleporterMessage( + ctx, + intermediateReceipt, + cChainInfo, + toL1, + true, + sendingKey, + nil, + signatureAggregator, + ) + + transferredAmount := big.NewInt(0).Sub(amount, input.SecondaryFee) + CheckBalance( + ctx, + recipientAddress, + big.NewInt(0).Add(initialBalance, transferredAmount), + toL1.RPCClient, + ) +} + +func SendERC20TokenMultiHopAndVerify( + ctx context.Context, + teleporter TeleporterTestInfo, + fundedKey *ecdsa.PrivateKey, + sendingKey *ecdsa.PrivateKey, + recipientAddress common.Address, + fromL1 interfaces.L1TestInfo, + fromTokenTransferrer *erc20tokenremote.ERC20TokenRemote, + fromTokenTransferrerAddress common.Address, + toL1 interfaces.L1TestInfo, + toTokenTransferrer *erc20tokenremote.ERC20TokenRemote, + toTokenTransferrerAddress common.Address, + cChainInfo interfaces.L1TestInfo, + amount *big.Int, + secondaryFeeAmount *big.Int, + signatureAggregator *SignatureAggregator, +) { + // Send tokens to the sender address to have gas for submitting the send tokens transaction + SendNativeTransfer( + ctx, + fromL1, + fundedKey, + crypto.PubkeyToAddress(sendingKey.PublicKey), + big.NewInt(1e18), + ) + input := erc20tokenremote.SendTokensInput{ + DestinationBlockchainID: toL1.BlockchainID, + DestinationTokenTransferrerAddress: toTokenTransferrerAddress, + Recipient: recipientAddress, + PrimaryFeeTokenAddress: common.Address{}, + PrimaryFee: big.NewInt(0), + SecondaryFee: secondaryFeeAmount, + RequiredGasLimit: DefaultERC20RequiredGas, + MultiHopFallback: recipientAddress, + } + + // Send tokens through a multi-hop transfer + originReceipt, amount := SendERC20TokenRemote( + ctx, + fromL1, + fromTokenTransferrer, + fromTokenTransferrerAddress, + input, + amount, + sendingKey, + ) + + // Relay the first message back to the home chain, in this case C-Chain, + // which then performs the multi-hop transfer to the destination TokenRemote instance. + intermediateReceipt := teleporter.RelayTeleporterMessage( + ctx, + originReceipt, + fromL1, + cChainInfo, + true, + fundedKey, + nil, + signatureAggregator, + ) + _, err := GetEventFromLogs( + intermediateReceipt.Logs, + teleporter.TeleporterMessenger(cChainInfo).ParseMessageExecuted, + ) + if err != nil { + TraceTransactionAndExit(ctx, cChainInfo.RPCClient, intermediateReceipt.TxHash) + } + + initialBalance, err := toTokenTransferrer.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + + // When we relay the above message to the home chain, a multi-hop transfer + // is performed to the destination TokenRemote instance. Parse for the send tokens event + // and relay to the destination TokenRemote instance. + remoteReceipt := teleporter.RelayTeleporterMessage( + ctx, + intermediateReceipt, + cChainInfo, + toL1, + true, + fundedKey, + nil, + signatureAggregator, + ) + _, err = GetEventFromLogs(remoteReceipt.Logs, teleporter.TeleporterMessenger(toL1).ParseMessageExecuted) + if err != nil { + TraceTransactionAndExit(ctx, toL1.RPCClient, remoteReceipt.TxHash) + } + + transferredAmount := big.NewInt(0).Sub(amount, input.SecondaryFee) + CheckERC20TokenRemoteWithdrawal( + ctx, + toTokenTransferrer, + remoteReceipt, + recipientAddress, + transferredAmount, + ) + + balance, err := toTokenTransferrer.BalanceOf(&bind.CallOpts{}, recipientAddress) + Expect(err).Should(BeNil()) + ExpectBigEqual(balance, big.NewInt(0).Add(initialBalance, transferredAmount)) +} + +func CheckERC20TokenHomeWithdrawal( + ctx context.Context, + erc20TokenHomeAddress common.Address, + exampleERC20 *exampleerc20.ExampleERC20Decimals, + receipt *types.Receipt, + expectedRecipientAddress common.Address, + expectedAmount *big.Int, +) { + homeTransferEvent, err := GetEventFromLogs(receipt.Logs, exampleERC20.ParseTransfer) + Expect(err).Should(BeNil()) + Expect(homeTransferEvent.From).Should(Equal(erc20TokenHomeAddress)) + Expect(homeTransferEvent.To).Should(Equal(expectedRecipientAddress)) + ExpectBigEqual(homeTransferEvent.Value, expectedAmount) +} + +func CheckERC20TokenRemoteWithdrawal( + ctx context.Context, + erc20TokenRemote *erc20tokenremote.ERC20TokenRemote, + receipt *types.Receipt, + expectedRecipientAddress common.Address, + expectedAmount *big.Int, +) { + transferEvent, err := GetEventFromLogs(receipt.Logs, erc20TokenRemote.ParseTransfer) + Expect(err).Should(BeNil()) + Expect(transferEvent.From).Should(Equal(common.Address{})) + Expect(transferEvent.To).Should(Equal(expectedRecipientAddress)) + ExpectBigEqual(transferEvent.Value, expectedAmount) +} + +func CheckNativeTokenHomeWithdrawal( + ctx context.Context, + nativeTokenHomeAddress common.Address, + wrappedNativeToken *wrappednativetoken.WrappedNativeToken, + receipt *types.Receipt, + expectedAmount *big.Int, +) { + withdrawalEvent, err := GetEventFromLogs(receipt.Logs, wrappedNativeToken.ParseWithdrawal) + Expect(err).Should(BeNil()) + Expect(withdrawalEvent.Sender).Should(Equal(nativeTokenHomeAddress)) + ExpectBigEqual(withdrawalEvent.Amount, expectedAmount) +} + +func GetTokenMultiplier( + decimalsShift uint8, +) *big.Int { + return big.NewInt(int64(math.Pow10(int(decimalsShift)))) +} + +type WrappedToken interface { + Deposit(opts *bind.TransactOpts) (*types.Transaction, error) + Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) +} + +func DepositAndApproveWrappedTokenForFees( + ctx context.Context, + l1 interfaces.L1TestInfo, + wrappedToken WrappedToken, + amount *big.Int, + spender common.Address, + senderKey *ecdsa.PrivateKey, +) { + if amount.Cmp(big.NewInt(0)) == 0 { + return + } + + // Deposit the native tokens for paying the fee + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = amount + tx, err := wrappedToken.Deposit(opts) + Expect(err).Should(BeNil()) + + _ = WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + opts, err = bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err = wrappedToken.Approve(opts, spender, amount) + Expect(err).Should(BeNil()) + + _ = WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} + +func ERC20DecimalsApprove( + ctx context.Context, + token *exampleerc20.ExampleERC20Decimals, + spender common.Address, + amount *big.Int, + l1 interfaces.L1TestInfo, + senderKey *ecdsa.PrivateKey, +) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := token.Approve(opts, spender, amount) + Expect(err).Should(BeNil()) + log.Info("Approved ERC20", "spender", spender.Hex(), "txHash", tx.Hash().Hex()) + + WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} diff --git a/icm-contracts/tests/utils/proxy.go b/icm-contracts/tests/utils/proxy.go new file mode 100644 index 000000000..0ec694a80 --- /dev/null +++ b/icm-contracts/tests/utils/proxy.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + + proxyadmin "github.com/ava-labs/icm-services/abi-bindings/go/ProxyAdmin" + transparentupgradeableproxy "github.com/ava-labs/icm-services/abi-bindings/go/TransparentUpgradeableProxy" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + . "github.com/onsi/gomega" +) + +func DeployTransparentUpgradeableProxy( + ctx context.Context, + l1 interfaces.L1TestInfo, + senderKey *ecdsa.PrivateKey, + implAddress common.Address, +) (common.Address, *proxyadmin.ProxyAdmin) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + l1.EVMChainID, + ) + Expect(err).Should((BeNil())) + + senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) + proxyAddress, tx, proxy, err := transparentupgradeableproxy.DeployTransparentUpgradeableProxy( + opts, + l1.RPCClient, + implAddress, + senderAddress, + []byte{}, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + proxyAdminEvent, err := GetEventFromLogs(receipt.Logs, proxy.ParseAdminChanged) + Expect(err).Should(BeNil()) + + proxyAdmin, err := proxyadmin.NewProxyAdmin(proxyAdminEvent.NewAdmin, l1.RPCClient) + Expect(err).Should(BeNil()) + + return proxyAddress, proxyAdmin +} diff --git a/icm-contracts/tests/utils/signature_aggregator.go b/icm-contracts/tests/utils/signature_aggregator.go new file mode 100644 index 000000000..ec37ec1b1 --- /dev/null +++ b/icm-contracts/tests/utils/signature_aggregator.go @@ -0,0 +1,194 @@ +package utils + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + "os/exec" + "time" + + "github.com/ava-labs/avalanchego/ids" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + "github.com/ava-labs/libevm/log" + + . "github.com/onsi/gomega" +) + +const ( + DEFAULT_API_PORT = 8080 + SIG_AGG_API_PATH = "/aggregate-signatures" +) + +// This is a wrapper around a signature aggregator binary instead of importing the package directly +// to avoid cyclic dependencies +type SignatureAggregator struct { + cmd *exec.Cmd + cancelFunc context.CancelFunc +} + +type SignatureAggregatorConfig struct { + PChainAPI ApiConfig `json:"p-chain-api"` + InfoAPI ApiConfig `json:"info-api"` + SubnetIDs []string `json:"tracked-subnet-ids"` + ApiPort int `json:"api-port"` + AllowPrivateIPs bool `json:"allow-private-ips"` +} + +type ApiConfig struct { + BaseURL string `json:"base-url"` + QueryParams map[string]string `json:"query-parameters"` + HTTPHeaders map[string]string `json:"http-headers"` +} + +type AggregateSignaturesRequest struct { + Message string `json:"message"` + Justification string `json:"justification,omitempty"` + SigningSubnetID string `json:"signing-subnet-id,omitempty"` + QuorumPercentage uint64 `json:"quorum-percentage,omitempty"` +} + +type SignatureAggregatorResponse struct { + SignedMessage string `json:"signed-message"` +} + +func (s *SignatureAggregator) Shutdown() { + s.cancelFunc() +} + +// Aggregator utils +func NewSignatureAggregator(apiUri string, subnetIDs []ids.ID) *SignatureAggregator { + sigAggPath := os.Getenv("SIG_AGG_PATH") + Expect(sigAggPath).ShouldNot(BeEmpty()) + subnetIDStrings := make([]string, 0, len(subnetIDs)) + for _, subnetID := range subnetIDs { + subnetIDStrings = append(subnetIDStrings, subnetID.String()) + } + cfg := SignatureAggregatorConfig{ + PChainAPI: ApiConfig{ + BaseURL: apiUri, + }, + InfoAPI: ApiConfig{ + BaseURL: apiUri, + }, + SubnetIDs: subnetIDStrings, + ApiPort: DEFAULT_API_PORT, + AllowPrivateIPs: true, + } + // write config to a JSON file in /tmp directory + configFile, err := os.CreateTemp("/tmp", "sig_agg_config_*.json") + Expect(err).Should(BeNil()) + defer configFile.Close() + + encoder := json.NewEncoder(configFile) + err = encoder.Encode(cfg) + Expect(err).Should(BeNil()) + + ctx, cancel := context.WithCancel(context.Background()) + + cmd := exec.CommandContext(ctx, sigAggPath, "--config-file", configFile.Name()) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err = cmd.Start() + Expect(err).Should(BeNil()) + go func() { + err := cmd.Wait() + // Context cancellation is the only expected way for the process to exit, otherwise log an error + // Don't panic to allow for easier cleanup + if !errors.Is(ctx.Err(), context.Canceled) { + log.Error("Signature aggregator exited abnormally", err) + } + }() + + // TODO: when the signature aggregator health check endpoint is improved to not return + // before ready to serve requests replace this sleep. + time.Sleep(time.Second * 5) + return &SignatureAggregator{ + cancelFunc: cancel, + cmd: cmd, + } +} + +func (s *SignatureAggregator) CreateSignedMessage( + unsignedMessage *avalancheWarp.UnsignedMessage, + justification []byte, + inputSigningSubnet ids.ID, + quorumPercentage uint64, +) (*avalancheWarp.Message, error) { + var err error + var signedMessage *avalancheWarp.Message + for i := 0; i < 3; i++ { + signedMessage, err = s.createSignedMessage(unsignedMessage, justification, inputSigningSubnet, quorumPercentage) + if err == nil { + return signedMessage, nil + } + time.Sleep(time.Second * 1) + } + return nil, err +} + +func (s *SignatureAggregator) createSignedMessage( + unsignedMessage *avalancheWarp.UnsignedMessage, + justification []byte, + inputSigningSubnet ids.ID, + quorumPercentage uint64, +) (*avalancheWarp.Message, error) { + client := &http.Client{ + Timeout: 20 * time.Second, + } + requestURL := fmt.Sprintf("http://localhost:%d%s", DEFAULT_API_PORT, SIG_AGG_API_PATH) + reqBody := AggregateSignaturesRequest{ + Message: hex.EncodeToString(unsignedMessage.Bytes()), + Justification: hex.EncodeToString(justification), + SigningSubnetID: inputSigningSubnet.String(), + QuorumPercentage: quorumPercentage, + } + + b, err := json.Marshal(reqBody) + if err != nil { + return nil, err + } + bodyReader := bytes.NewReader(b) + + req, err := http.NewRequest(http.MethodPost, requestURL, bodyReader) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + res, err := client.Do(req) + if err != nil { + return nil, err + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("expected status code 200, got %d", res.StatusCode) + } + + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + + var response SignatureAggregatorResponse + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + + decodedMessage, err := hex.DecodeString(response.SignedMessage) + if err != nil { + return nil, err + } + + signedMessage, err := avalancheWarp.ParseMessage(decodedMessage) + if err != nil { + return nil, err + } + + return signedMessage, nil +} diff --git a/icm-contracts/tests/utils/teleporter.go b/icm-contracts/tests/utils/teleporter.go new file mode 100644 index 000000000..102cb1b69 --- /dev/null +++ b/icm-contracts/tests/utils/teleporter.go @@ -0,0 +1,895 @@ +package utils + +import ( + "bytes" + "context" + "crypto/ecdsa" + "encoding/json" + "fmt" + "io/fs" + "math/big" + "os" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/evm/predicate" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + validatorsetsig "github.com/ava-labs/icm-services/abi-bindings/go/governance/ValidatorSetSig" + exampleerc20 "github.com/ava-labs/icm-services/abi-bindings/go/mocks/ExampleERC20" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + teleporterregistry "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/registry/TeleporterRegistry" + testmessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/tests/TestMessenger" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + deploymentUtils "github.com/ava-labs/icm-services/icm-contracts/utils/deployment-utils" + gasUtils "github.com/ava-labs/icm-services/icm-contracts/utils/gas-utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + "github.com/ava-labs/subnet-evm/rpc" + . "github.com/onsi/gomega" +) + +var ( + DefaultTeleporterTransactionGas uint64 = 300_000 + DefaultTeleporterTransactionValue = common.Big0 +) + +type ChainTeleporterInfo struct { + TeleporterRegistry *teleporterregistry.TeleporterRegistry + TeleporterRegistryAddress common.Address + + TeleporterMessenger *teleportermessenger.TeleporterMessenger + TeleporterMessengerAddress common.Address +} + +type TeleporterTestInfo map[ids.ID]*ChainTeleporterInfo + +func NewTeleporterTestInfo(l1s []interfaces.L1TestInfo) TeleporterTestInfo { + t := make(TeleporterTestInfo) + for _, l1 := range l1s { + t[l1.BlockchainID] = &ChainTeleporterInfo{} + } + return t +} + +func (t TeleporterTestInfo) TeleporterMessenger( + l1 interfaces.L1TestInfo, +) *teleportermessenger.TeleporterMessenger { + return t[l1.BlockchainID].TeleporterMessenger +} + +func (t TeleporterTestInfo) TeleporterMessengerAddress(l1 interfaces.L1TestInfo) common.Address { + return t[l1.BlockchainID].TeleporterMessengerAddress +} + +func (t TeleporterTestInfo) TeleporterRegistry( + l1 interfaces.L1TestInfo, +) *teleporterregistry.TeleporterRegistry { + return t[l1.BlockchainID].TeleporterRegistry +} + +func (t TeleporterTestInfo) TeleporterRegistryAddress(l1 interfaces.L1TestInfo) common.Address { + return t[l1.BlockchainID].TeleporterRegistryAddress +} + +func (t TeleporterTestInfo) SetTeleporter(address common.Address, l1 interfaces.L1TestInfo) { + teleporterMessenger, err := teleportermessenger.NewTeleporterMessenger( + address, l1.RPCClient, + ) + Expect(err).Should(BeNil()) + info := t[l1.BlockchainID] + info.TeleporterMessengerAddress = address + info.TeleporterMessenger = teleporterMessenger +} + +func (t TeleporterTestInfo) SetTeleporterRegistry(address common.Address, l1 interfaces.L1TestInfo) { + teleporterRegistry, err := teleporterregistry.NewTeleporterRegistry( + address, l1.RPCClient, + ) + Expect(err).Should(BeNil()) + info := t[l1.BlockchainID] + info.TeleporterRegistryAddress = address + info.TeleporterRegistry = teleporterRegistry +} + +func (t TeleporterTestInfo) InitializeBlockchainID(l1 interfaces.L1TestInfo, fundedKey *ecdsa.PrivateKey) { + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := t.TeleporterMessenger(l1).InitializeBlockchainID(opts) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(context.Background(), l1, tx.Hash()) +} + +func (t TeleporterTestInfo) DeployTeleporterRegistry(l1 interfaces.L1TestInfo, deployerKey *ecdsa.PrivateKey) { + ctx := context.Background() + entries := []teleporterregistry.ProtocolRegistryEntry{ + { + Version: big.NewInt(1), + ProtocolAddress: t.TeleporterMessengerAddress(l1), + }, + } + opts, err := bind.NewKeyedTransactorWithChainID(deployerKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + teleporterRegistryAddress, tx, teleporterRegistry, err := teleporterregistry.DeployTeleporterRegistry( + opts, l1.RPCClient, entries, + ) + Expect(err).Should(BeNil()) + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + info := t[l1.BlockchainID] + info.TeleporterRegistryAddress = teleporterRegistryAddress + info.TeleporterRegistry = teleporterRegistry +} + +func (t TeleporterTestInfo) DeployTeleporterMessenger( + ctx context.Context, + l1 interfaces.L1TestInfo, + transactionBytes []byte, + deployerAddress common.Address, + contractAddress common.Address, + fundedKey *ecdsa.PrivateKey, +) { + // Fund the deployer address + fundAmount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(11)) // 11 AVAX + fundDeployerTx := CreateNativeTransferTransaction( + ctx, l1, fundedKey, deployerAddress, fundAmount, + ) + SendTransactionAndWaitForSuccess(ctx, l1, fundDeployerTx) + + log.Info("Finished funding Teleporter deployer", "blockchainID", l1.BlockchainID.Hex()) + + // Deploy Teleporter contract + rpcClient, err := rpc.DialContext( + ctx, + HttpToRPCURI(l1.NodeURIs[0], l1.BlockchainID.String()), + ) + Expect(err).Should(BeNil()) + defer rpcClient.Close() + + txHash := common.Hash{} + err = rpcClient.CallContext(ctx, &txHash, "eth_sendRawTransaction", hexutil.Encode(transactionBytes)) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, txHash) + + teleporterCode, err := l1.RPCClient.CodeAt(ctx, contractAddress, nil) + Expect(err).Should(BeNil()) + Expect(len(teleporterCode)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode +} + +func (t TeleporterTestInfo) RelayTeleporterMessage( + ctx context.Context, + sourceReceipt *types.Receipt, + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + expectSuccess bool, + fundedKey *ecdsa.PrivateKey, + justification []byte, + signatureAggregator *SignatureAggregator, +) *types.Receipt { + // Fetch the Teleporter message from the logs + signedWarpMessage := ConstructSignedWarpMessage( + ctx, + sourceReceipt, + source, + destination, + justification, + signatureAggregator, + ) + + // Construct the transaction to send the Warp message to the destination chain + signedTx := CreateReceiveCrossChainMessageTransaction( + ctx, + signedWarpMessage, + t.TeleporterMessengerAddress(source), + fundedKey, + destination, + ) + + log.Info("Sending transaction to destination chain") + if !expectSuccess { + return SendTransactionAndWaitForFailure(ctx, destination, signedTx) + } + + receipt := SendTransactionAndWaitForSuccess(ctx, destination, signedTx) + + // Check the transaction logs for the ReceiveCrossChainMessage event emitted by the Teleporter contract + receiveEvent, err := GetEventFromLogs( + receipt.Logs, + t.TeleporterMessenger(destination).ParseReceiveCrossChainMessage, + ) + fmt.Println("receiveEvent", receiveEvent) + Expect(err).Should(BeNil()) + Expect(receiveEvent.SourceBlockchainID[:]).Should(Equal(source.BlockchainID[:])) + return receipt +} + +func (t TeleporterTestInfo) SendExampleCrossChainMessageAndVerify( + ctx context.Context, + source interfaces.L1TestInfo, + sourceExampleMessenger *testmessenger.TestMessenger, + destination interfaces.L1TestInfo, + destExampleMessengerAddress common.Address, + destExampleMessenger *testmessenger.TestMessenger, + senderKey *ecdsa.PrivateKey, + message string, + signatureAggregator *SignatureAggregator, + expectSuccess bool, +) { + // Call the example messenger contract on L1 A + optsA, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := sourceExampleMessenger.SendMessage( + optsA, + destination.BlockchainID, + destExampleMessengerAddress, + common.BigToAddress(common.Big0), + big.NewInt(0), + testmessenger.SendMessageRequiredGas, + message, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + receipt := WaitForTransactionSuccess(ctx, source, tx.Hash()) + + sourceTeleporterMessenger := t.TeleporterMessenger(source) + destTeleporterMessenger := t.TeleporterMessenger(destination) + + event, err := GetEventFromLogs(receipt.Logs, sourceTeleporterMessenger.ParseSendCrossChainMessage) + Expect(err).Should(BeNil()) + Expect(event.DestinationBlockchainID[:]).Should(Equal(destination.BlockchainID[:])) + + teleporterMessageID := event.MessageID + + // + // Relay the message to the destination + // + receipt = t.RelayTeleporterMessage(ctx, receipt, source, destination, true, senderKey, nil, signatureAggregator) + + // + // Check Teleporter message received on the destination + // + delivered, err := destTeleporterMessenger.MessageReceived( + &bind.CallOpts{}, teleporterMessageID, + ) + Expect(err).Should(BeNil()) + Expect(delivered).Should(BeTrue()) + + if expectSuccess { + // Check that message execution was successful + messageExecutedEvent, err := GetEventFromLogs( + receipt.Logs, + destTeleporterMessenger.ParseMessageExecuted, + ) + Expect(err).Should(BeNil()) + Expect(messageExecutedEvent.MessageID[:]).Should(Equal(teleporterMessageID[:])) + } else { + // Check that message execution failed + messageExecutionFailedEvent, err := GetEventFromLogs( + receipt.Logs, + destTeleporterMessenger.ParseMessageExecutionFailed, + ) + Expect(err).Should(BeNil()) + Expect(messageExecutionFailedEvent.MessageID[:]).Should(Equal(teleporterMessageID[:])) + } + + // + // Verify we received the expected string + // + _, currMessage, err := destExampleMessenger.GetCurrentMessage(&bind.CallOpts{}, source.BlockchainID) + Expect(err).Should(BeNil()) + if expectSuccess { + Expect(currMessage).Should(Equal(message)) + } else { + Expect(currMessage).ShouldNot(Equal(message)) + } +} + +func (t TeleporterTestInfo) AddProtocolVersionAndWaitForAcceptance( + ctx context.Context, + l1 interfaces.L1TestInfo, + newTeleporterAddress common.Address, + senderKey *ecdsa.PrivateKey, + unsignedMessage *avalancheWarp.UnsignedMessage, + signatureAggregator *SignatureAggregator, +) { + signedWarpMsg := GetSignedMessage(l1, l1, unsignedMessage, nil, signatureAggregator) + log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) + + // Construct tx to add protocol version and send to destination chain + signedTx := CreateAddProtocolVersionTransaction( + ctx, + signedWarpMsg, + t.TeleporterRegistryAddress(l1), + senderKey, + l1, + ) + + curLatestVersion := t.GetLatestTeleporterVersion(l1) + expectedLatestVersion := big.NewInt(curLatestVersion.Int64() + 1) + + // Wait for tx to be accepted, and verify events emitted + receipt := SendTransactionAndWaitForSuccess(ctx, l1, signedTx) + teleporterRegistry := t.TeleporterRegistry(l1) + addProtocolVersionEvent, err := GetEventFromLogs(receipt.Logs, teleporterRegistry.ParseAddProtocolVersion) + Expect(err).Should(BeNil()) + Expect(addProtocolVersionEvent.Version.Cmp(expectedLatestVersion)).Should(Equal(0)) + Expect(addProtocolVersionEvent.ProtocolAddress).Should(Equal(newTeleporterAddress)) + + versionUpdatedEvent, err := GetEventFromLogs(receipt.Logs, teleporterRegistry.ParseLatestVersionUpdated) + Expect(err).Should(BeNil()) + Expect(versionUpdatedEvent.OldVersion.Cmp(curLatestVersion)).Should(Equal(0)) + Expect(versionUpdatedEvent.NewVersion.Cmp(expectedLatestVersion)).Should(Equal(0)) +} + +func (t TeleporterTestInfo) GetLatestTeleporterVersion(l1 interfaces.L1TestInfo) *big.Int { + version, err := t.TeleporterRegistry(l1).LatestVersion(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + return version +} + +func (t TeleporterTestInfo) ClearReceiptQueue( + ctx context.Context, + fundedKey *ecdsa.PrivateKey, + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + signatureAggregator *SignatureAggregator, +) { + sourceTeleporterMessenger := t.TeleporterMessenger(source) + outstandReceiptCount := GetOutstandingReceiptCount( + t.TeleporterMessenger(source), + destination.BlockchainID, + ) + for outstandReceiptCount.Cmp(big.NewInt(0)) != 0 { + log.Info("Emptying receipt queue", "remainingReceipts", outstandReceiptCount.String()) + // Send message from L1 B to L1 A to trigger the "regular" method of delivering receipts. + // The next message from B->A will contain the same receipts that were manually sent in the above steps, + // but they should not be processed again on L1 A. + sendCrossChainMessageInput := teleportermessenger.TeleporterMessageInput{ + DestinationBlockchainID: destination.BlockchainID, + DestinationAddress: common.HexToAddress("0x1111111111111111111111111111111111111111"), + RequiredGasLimit: big.NewInt(1), + FeeInfo: teleportermessenger.TeleporterFeeInfo{ + FeeTokenAddress: common.Address{}, + Amount: big.NewInt(0), + }, + AllowedRelayerAddresses: []common.Address{}, + Message: []byte{1, 2, 3, 4}, + } + + // This message will also have the same receipts as the previous message + receipt, _ := SendCrossChainMessageAndWaitForAcceptance( + ctx, sourceTeleporterMessenger, source, destination, sendCrossChainMessageInput, fundedKey) + + // Relay message + t.RelayTeleporterMessage(ctx, receipt, source, destination, true, fundedKey, nil, signatureAggregator) + + outstandReceiptCount = GetOutstandingReceiptCount(sourceTeleporterMessenger, destination.BlockchainID) + } + log.Info("Receipt queue emptied") +} + +// Deploys a new version of Teleporter and returns its address +// Does NOT modify the global Teleporter contract address to provide greater testing flexibility. +func (t TeleporterTestInfo) DeployNewTeleporterVersion( + ctx context.Context, + l1 interfaces.L1TestInfo, + fundedKey *ecdsa.PrivateKey, + teleporterByteCodeFile string, +) common.Address { + contractCreationGasPrice := (&big.Int{}).Add(deploymentUtils.GetDefaultContractCreationGasPrice(), big.NewInt(1)) + teleporterDeployerTransaction, + _, + teleporterDeployerAddress, + teleporterContractAddress, + err := deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + contractCreationGasPrice, + ) + Expect(err).Should(BeNil()) + + t.DeployTeleporterMessenger( + ctx, + l1, + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + + return teleporterContractAddress +} + +// +// Deployment utils +// + +func DeployTestMessenger( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + teleporterManager common.Address, + registryAddress common.Address, + l1 interfaces.L1TestInfo, +) (common.Address, *testmessenger.TestMessenger) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + l1.EVMChainID, + ) + Expect(err).Should(BeNil()) + address, tx, exampleMessenger, err := testmessenger.DeployTestMessenger( + opts, + l1.RPCClient, + registryAddress, + teleporterManager, + big.NewInt(1), + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return address, exampleMessenger +} + +// +// Parsing utils +// + +func ParseTeleporterMessage(unsignedMessage avalancheWarp.UnsignedMessage) *teleportermessenger.TeleporterMessage { + addressedPayload, err := payload.ParseAddressedCall(unsignedMessage.Payload) + Expect(err).Should(BeNil()) + + teleporterMessage := teleportermessenger.TeleporterMessage{} + err = teleporterMessage.Unpack(addressedPayload.Payload) + Expect(err).Should(BeNil()) + + return &teleporterMessage +} + +// +// Function call utils +// + +func SendAddFeeAmountAndWaitForAcceptance( + ctx context.Context, + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + messageID ids.ID, + amount *big.Int, + feeContractAddress common.Address, + senderKey *ecdsa.PrivateKey, + transactor *teleportermessenger.TeleporterMessenger, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + source.EVMChainID, + ) + Expect(err).Should(BeNil()) + + tx, err := transactor.AddFeeAmount(opts, messageID, feeContractAddress, amount) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, source, tx.Hash()) + + addFeeAmountEvent, err := GetEventFromLogs(receipt.Logs, transactor.ParseAddFeeAmount) + Expect(err).Should(BeNil()) + Expect(addFeeAmountEvent.MessageID[:]).Should(Equal(messageID[:])) + + log.Info("Send AddFeeAmount transaction on source chain", + "messageID", messageID, + "sourceChainID", source.BlockchainID, + "destinationBlockchainID", destination.BlockchainID, + ) + + return receipt +} + +func RetryMessageExecutionAndWaitForAcceptance( + ctx context.Context, + sourceBlockchainID ids.ID, + destinationTeleporterMessenger *teleportermessenger.TeleporterMessenger, + destinationL1 interfaces.L1TestInfo, + message teleportermessenger.TeleporterMessage, + senderKey *ecdsa.PrivateKey, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, destinationL1.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := destinationTeleporterMessenger.RetryMessageExecution(opts, sourceBlockchainID, message) + Expect(err).Should(BeNil()) + + return WaitForTransactionSuccess(ctx, destinationL1, tx.Hash()) +} + +func RedeemRelayerRewardsAndConfirm( + ctx context.Context, + teleporterMessenger *teleportermessenger.TeleporterMessenger, + l1 interfaces.L1TestInfo, + feeToken *exampleerc20.ExampleERC20, + feeTokenAddress common.Address, + redeemerKey *ecdsa.PrivateKey, + expectedAmount *big.Int, +) *types.Receipt { + redeemerAddress := crypto.PubkeyToAddress(redeemerKey.PublicKey) + + // Check the ERC20 balance before redemption + balanceBeforeRedemption, err := feeToken.BalanceOf( + &bind.CallOpts{}, redeemerAddress, + ) + Expect(err).Should(BeNil()) + + // Redeem the rewards + txOpts, err := bind.NewKeyedTransactorWithChainID( + redeemerKey, l1.EVMChainID, + ) + Expect(err).Should(BeNil()) + tx, err := teleporterMessenger.RedeemRelayerRewards( + txOpts, feeTokenAddress, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + // Check that the ERC20 balance was incremented + balanceAfterRedemption, err := feeToken.BalanceOf( + &bind.CallOpts{}, redeemerAddress, + ) + Expect(err).Should(BeNil()) + Expect(balanceAfterRedemption).Should( + Equal( + big.NewInt(0).Add( + balanceBeforeRedemption, expectedAmount, + ), + ), + ) + + // Check that the redeemable rewards amount is now zero. + updatedRewardAmount, err := teleporterMessenger.CheckRelayerRewardAmount( + &bind.CallOpts{}, + redeemerAddress, + feeTokenAddress, + ) + Expect(err).Should(BeNil()) + Expect(updatedRewardAmount.Cmp(big.NewInt(0))).Should(Equal(0)) + + return receipt +} + +func SendSpecifiedReceiptsAndWaitForAcceptance( + ctx context.Context, + sourceTeleporterMessenger *teleportermessenger.TeleporterMessenger, + source interfaces.L1TestInfo, + destinationBlockchainID ids.ID, + messageIDs [][32]byte, + feeInfo teleportermessenger.TeleporterFeeInfo, + allowedRelayerAddresses []common.Address, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, ids.ID) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := sourceTeleporterMessenger.SendSpecifiedReceipts( + opts, destinationBlockchainID, messageIDs, feeInfo, allowedRelayerAddresses) + Expect(err).Should(BeNil()) + + receipt := WaitForTransactionSuccess(ctx, source, tx.Hash()) + + // Check the transaction logs for the SendCrossChainMessage event emitted by the Teleporter contract + event, err := GetEventFromLogs(receipt.Logs, sourceTeleporterMessenger.ParseSendCrossChainMessage) + Expect(err).Should(BeNil()) + Expect(event.DestinationBlockchainID[:]).Should(Equal(destinationBlockchainID[:])) + + log.Info("Sending SendSpecifiedReceipts transaction", + "destinationBlockchainID", destinationBlockchainID, + "txHash", tx.Hash()) + + return receipt, event.MessageID +} + +func SendCrossChainMessageAndWaitForAcceptance( + ctx context.Context, + sourceTeleporterMessenger *teleportermessenger.TeleporterMessenger, + source interfaces.L1TestInfo, + destination interfaces.L1TestInfo, + input teleportermessenger.TeleporterMessageInput, + senderKey *ecdsa.PrivateKey, +) (*types.Receipt, ids.ID) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + + // Send a transaction to the Teleporter contract + tx, err := sourceTeleporterMessenger.SendCrossChainMessage(opts, input) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be accepted + receipt := WaitForTransactionSuccess(ctx, source, tx.Hash()) + + // Check the transaction logs for the SendCrossChainMessage event emitted by the Teleporter contract + event, err := GetEventFromLogs(receipt.Logs, sourceTeleporterMessenger.ParseSendCrossChainMessage) + Expect(err).Should(BeNil()) + + log.Info("Sending SendCrossChainMessage transaction on source chain", + "sourceChainID", source.BlockchainID, + "destinationBlockchainID", destination.BlockchainID, + "txHash", tx.Hash()) + + return receipt, event.MessageID +} + +// Returns true if the transaction receipt contains a ReceiptReceived log with the specified messageID +func CheckReceiptReceived( + receipt *types.Receipt, + messageID [32]byte, + transactor *teleportermessenger.TeleporterMessenger, +) bool { + for _, log := range receipt.Logs { + event, err := transactor.ParseReceiptReceived(*log) + if err == nil && bytes.Equal(event.MessageID[:], messageID[:]) { + return true + } + } + return false +} + +func GetOutstandingReceiptCount( + teleporterMessenger *teleportermessenger.TeleporterMessenger, + destinationBlockchainID ids.ID, +) *big.Int { + size, err := teleporterMessenger.GetReceiptQueueSize(&bind.CallOpts{}, destinationBlockchainID) + Expect(err).Should(BeNil()) + return size +} + +// +// Transaction utils +// + +// Constructs a transaction to call sendCrossChainMessage +// Returns the signed transaction. +func CreateSendCrossChainMessageTransaction( + ctx context.Context, + source interfaces.L1TestInfo, + input teleportermessenger.TeleporterMessageInput, + senderKey *ecdsa.PrivateKey, + teleporterContractAddress common.Address, +) *types.Transaction { + data, err := teleportermessenger.PackSendCrossChainMessage(input) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, source, PrivateKeyToAddress(senderKey)) + + // Send a transaction to the Teleporter contract + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: source.EVMChainID, + Nonce: nonce, + To: &teleporterContractAddress, + Gas: DefaultTeleporterTransactionGas, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: DefaultTeleporterTransactionValue, + Data: data, + }) + + return SignTransaction(tx, senderKey, source.EVMChainID) +} + +// Constructs a transaction to call receiveCrossChainMessage +// Returns the signed transaction. +func CreateReceiveCrossChainMessageTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + teleporterContractAddress common.Address, + senderKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, +) *types.Transaction { + // Construct the transaction to send the Warp message to the destination chain + log.Info("Constructing receiveCrossChainMessage transaction for the destination chain") + numSigners, err := signedMessage.Signature.NumSigners() + Expect(err).Should(BeNil()) + + teleporterMessage := ParseTeleporterMessage(signedMessage.UnsignedMessage) + upgradeRules := upgrade.GetConfig(constants.MainnetID) + gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit( + &gasUtils.UpgradeRules{UpgradeConfig: upgradeRules}, + numSigners, + teleporterMessage.RequiredGasLimit, + len(predicate.New(signedMessage.Bytes())), + len(signedMessage.Payload), + len(teleporterMessage.Receipts), + ) + Expect(err).Should(BeNil()) + + callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, PrivateKeyToAddress(senderKey)) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, l1Info, PrivateKeyToAddress(senderKey)) + + destinationTx := types.NewTx(&types.DynamicFeeTx{ + ChainID: l1Info.EVMChainID, + Nonce: nonce, + To: &teleporterContractAddress, + Gas: gasLimit, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: common.Big0, + Data: callData, + AccessList: types.AccessList{ + { + Address: warp.ContractAddress, + StorageKeys: predicate.New(signedMessage.Bytes()), + }, + }, + }) + + return SignTransaction(destinationTx, senderKey, l1Info.EVMChainID) +} + +// Constructs a transaction to call addProtocolVersion +// Returns the signed transaction. +func CreateAddProtocolVersionTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + teleporterRegistryAddress common.Address, + senderKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, +) *types.Transaction { + // Construct the transaction to send the Warp message to the destination chain + log.Info("Constructing addProtocolVersion transaction for the destination chain") + + callData, err := teleporterregistry.PackAddProtocolVersion(0) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, l1Info, PrivateKeyToAddress(senderKey)) + + destinationTx := types.NewTx(&types.DynamicFeeTx{ + ChainID: l1Info.EVMChainID, + Nonce: nonce, + To: &teleporterRegistryAddress, + Gas: 500_000, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: common.Big0, + Data: callData, + AccessList: types.AccessList{ + { + Address: warp.ContractAddress, + StorageKeys: predicate.New(signedMessage.Bytes()), + }, + }, + }) + + return SignTransaction(destinationTx, senderKey, l1Info.EVMChainID) +} + +func CreateExecuteCallPredicateTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + validatorSetSigAddress common.Address, + senderKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, +) *types.Transaction { + log.Info("Constructing executeCall transaction for the destination chain") + + callData, err := validatorsetsig.PackExecuteCall(0) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, l1Info, PrivateKeyToAddress(senderKey)) + + destinationTx := types.NewTx(&types.DynamicFeeTx{ + ChainID: l1Info.EVMChainID, + Nonce: nonce, + To: &validatorSetSigAddress, + Gas: 500_000, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: common.Big0, + Data: callData, + AccessList: types.AccessList{ + { + Address: warp.ContractAddress, + StorageKeys: predicate.New(signedMessage.Bytes()), + }, + }, + }) + return SignTransaction(destinationTx, senderKey, l1Info.EVMChainID) +} + +// +// Off-chain message utils +// + +// Creates an Warp message that registers a Teleporter protocol version with TeleporterRegistry. +// Returns the Warp message, as well as the chain config adding the message to the list of approved +// off-chain Warp messages +func InitOffChainMessageChainConfig( + networkID uint32, + l1 interfaces.L1TestInfo, + registryAddress common.Address, + teleporterAddress common.Address, + version uint64, +) (*avalancheWarp.UnsignedMessage, string) { + unsignedMessage := CreateOffChainRegistryMessage( + networkID, + l1, + registryAddress, + teleporterregistry.ProtocolRegistryEntry{ + Version: big.NewInt(int64(version)), + ProtocolAddress: teleporterAddress, + }, + ) + log.Info("Adding off-chain message to Warp chain config", + "messageID", unsignedMessage.ID(), + "blockchainID", l1.BlockchainID.String(), + ) + + return unsignedMessage, GetChainConfigWithOffChainMessages([]avalancheWarp.UnsignedMessage{*unsignedMessage}) +} + +// Creates an off-chain Warp message that registers a Teleporter protocol version with TeleporterRegistry +func CreateOffChainRegistryMessage( + networkID uint32, + l1 interfaces.L1TestInfo, + registryAddress common.Address, + entry teleporterregistry.ProtocolRegistryEntry, +) *avalancheWarp.UnsignedMessage { + sourceAddress := []byte{} + payloadBytes, err := teleporterregistry.PackTeleporterRegistryWarpPayload(entry, registryAddress) + Expect(err).Should(BeNil()) + + addressedPayload, err := payload.NewAddressedCall(sourceAddress, payloadBytes) + Expect(err).Should(BeNil()) + + unsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + l1.BlockchainID, + addressedPayload.Bytes(), + ) + Expect(err).Should(BeNil()) + + return unsignedMessage +} + +func SaveRegistyAddress( + teleporterInfo TeleporterTestInfo, + fileName string, +) { + // Save the Teleporter registry address and validator addresses to files + registryAddresseses := make(map[string]string) + for l1, teleporterInfo := range teleporterInfo { + registryAddresseses[l1.Hex()] = teleporterInfo.TeleporterRegistryAddress.Hex() + } + + jsonData, err := json.Marshal(registryAddresseses) + Expect(err).Should(BeNil()) + err = os.WriteFile(fileName, jsonData, fs.ModePerm) + Expect(err).Should(BeNil()) +} + +func SetTeleporterInfoFromFile( + fileName string, + teleporterContractAddress common.Address, + teleporterInfo TeleporterTestInfo, + l1s []interfaces.L1TestInfo, +) { + // Read the Teleporter registry address from the file + registryAddresseses := make(map[string]string) + data, err := os.ReadFile(fileName) + Expect(err).Should(BeNil()) + err = json.Unmarshal(data, ®istryAddresseses) + Expect(err).Should(BeNil()) + + for _, l1 := range l1s { + teleporterInfo.SetTeleporter(teleporterContractAddress, l1) + teleporterInfo.SetTeleporterRegistry( + common.HexToAddress(registryAddresseses[l1.BlockchainID.Hex()]), + l1, + ) + } +} diff --git a/icm-contracts/tests/utils/token_scaling.go b/icm-contracts/tests/utils/token_scaling.go new file mode 100644 index 000000000..365a56a93 --- /dev/null +++ b/icm-contracts/tests/utils/token_scaling.go @@ -0,0 +1,106 @@ +package utils + +import ( + "math/big" + + "github.com/ava-labs/avalanchego/ids" + erc20tokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/ERC20TokenHome" + nativetokenhome "github.com/ava-labs/icm-services/abi-bindings/go/ictt/TokenHome/NativeTokenHome" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + + . "github.com/onsi/gomega" +) + +// ApplyTokenScaling applies token scaling to the given amount of home tokens. +// Token scaling is applied when sending tokens from the home to the TokenRemote instances. +func ApplyTokenScaling( + tokenMultiplier *big.Int, + multiplyOnRemote bool, + homeTokenAmount *big.Int, +) *big.Int { + return scaleTokens(tokenMultiplier, multiplyOnRemote, homeTokenAmount, true) +} + +// RemoveTokenScaling removes token scaling from the given amount of remote tokens. +// Token scaling is removed when sending tokens from the remote back to the TokenHome instance. +func RemoveTokenScaling( + tokenMultiplier *big.Int, + multiplyOnRemote bool, + remoteTokenAmount *big.Int, +) *big.Int { + return scaleTokens(tokenMultiplier, multiplyOnRemote, remoteTokenAmount, false) +} + +func scaleTokens( + tokenMultiplier *big.Int, + multiplyOnRemote bool, + amount *big.Int, + isSendToRemote bool, +) *big.Int { + // Multiply when multiplyOnRemote and isSendToRemote are + // both true or both false. + if multiplyOnRemote == isSendToRemote { + return big.NewInt(0).Mul(amount, tokenMultiplier) + } + + return big.NewInt(0).Div(amount, tokenMultiplier) +} + +// GetScaledAmountFromERC20TokenHome returns the scaled amount of remote tokens that +// will be sent to the remote token transferrer for an amount of home tokens. +func GetScaledAmountFromERC20TokenHome( + erc20TokenHome *erc20tokenhome.ERC20TokenHome, + remoteBlockchainID ids.ID, + remoteAddress common.Address, + homeTokenAmount *big.Int, +) *big.Int { + remoteSettings, err := erc20TokenHome.GetRemoteTokenTransferrerSettings( + &bind.CallOpts{}, + remoteBlockchainID, + remoteAddress, + ) + Expect(err).Should(BeNil()) + + return ApplyTokenScaling( + remoteSettings.TokenMultiplier, + remoteSettings.MultiplyOnRemote, + homeTokenAmount, + ) +} + +// GetScaledAmountFromNativeTokenHome returns the scaled amount of tokens that will be sent to +// the remote token transferrer for corresponding amount of home tokens. +func GetScaledAmountFromNativeTokenHome( + nativeTokenHome *nativetokenhome.NativeTokenHome, + remoteBlockchainID ids.ID, + remoteAddress common.Address, + amount *big.Int, +) *big.Int { + remoteSettings, err := nativeTokenHome.GetRemoteTokenTransferrerSettings( + &bind.CallOpts{}, + remoteBlockchainID, + remoteAddress, + ) + Expect(err).Should(BeNil()) + + return ApplyTokenScaling( + remoteSettings.TokenMultiplier, + remoteSettings.MultiplyOnRemote, + amount, + ) +} + +func calculateCollateralNeeded( + initialReserveImbalance *big.Int, + tokenMultiplier *big.Int, + multiplyOnRemote bool, +) *big.Int { + collateralNeeded := RemoveTokenScaling(tokenMultiplier, multiplyOnRemote, initialReserveImbalance) + + remainder := big.NewInt(0).Mod(collateralNeeded, tokenMultiplier) + if multiplyOnRemote && (remainder.Cmp(big.NewInt(0)) != 0) { + collateralNeeded.Add(collateralNeeded, big.NewInt(1)) + } + return collateralNeeded +} diff --git a/icm-contracts/tests/utils/validator_manager.go b/icm-contracts/tests/utils/validator_manager.go new file mode 100644 index 000000000..f01b47f56 --- /dev/null +++ b/icm-contracts/tests/utils/validator_manager.go @@ -0,0 +1,1806 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "crypto/sha256" + "encoding/binary" + "fmt" + "log" + "math/big" + "reflect" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/proto/pb/platformvm" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/evm/predicate" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + warpMessage "github.com/ava-labs/avalanchego/vms/platformvm/warp/message" + warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + pwallet "github.com/ava-labs/avalanchego/wallet/chain/p/wallet" + proxyadmin "github.com/ava-labs/icm-services/abi-bindings/go/ProxyAdmin" + exampleerc20 "github.com/ava-labs/icm-services/abi-bindings/go/mocks/ExampleERC20" + acp99manager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ACP99Manager" + erc20tokenstakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ERC20TokenStakingManager" + examplerewardcalculator "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ExampleRewardCalculator" + nativetokenstakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/NativeTokenStakingManager" + poamanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/PoAManager" + validatormanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/ValidatorManager" + istakingmanager "github.com/ava-labs/icm-services/abi-bindings/go/validator-manager/interfaces/IStakingManager" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + subnetEvmUtils "github.com/ava-labs/subnet-evm/tests/utils" + "github.com/ava-labs/subnet-evm/warp/messages" + "google.golang.org/protobuf/proto" + + . "github.com/onsi/gomega" +) + +const ( + DefaultMinDelegateFeeBips uint16 = 1 + DefaultMinStakeDurationSeconds uint64 = 1 + DefaultMinStakeAmount uint64 = 1e16 + DefaultMaxStakeAmount uint64 = 10e18 + DefaultMaxStakeMultiplier uint8 = 4 + DefaultMaxChurnPercentage uint8 = 20 + DefaultChurnPeriodSeconds uint64 = 1 + DefaultWeightToValueFactor uint64 = 1e12 + DefaultPChainAddress string = "P-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u" + DefaultRewardRecipientAddress string = "0x000000000000000000000000000000000000002a" +) + +type ValidatorManagerConcreteType int + +const ( + PoAValidatorManager ValidatorManagerConcreteType = iota + ERC20TokenStakingManager + NativeTokenStakingManager +) + +// +// Deployment utils +// + +func DeployValidatorManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + proxy bool, +) (common.Address, *proxyadmin.ProxyAdmin) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + // Reset the global binary data for better test isolation + validatormanager.ValidatorManagerBin = validatormanager.ValidatorManagerMetaData.Bin + + address, tx, _, err := validatormanager.DeployValidatorManager( + opts, + l1.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + var proxyAdmin *proxyadmin.ProxyAdmin + if proxy { + // Overwrite the manager address with the proxy address + address, proxyAdmin = DeployTransparentUpgradeableProxy( + ctx, + l1, + senderKey, + address, + ) + } + + return address, proxyAdmin +} + +func InitializeValidatorManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + validatorManager *validatormanager.ValidatorManager, + adminAddress common.Address, +) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := validatorManager.Initialize( + opts, + validatormanager.ValidatorManagerSettings{ + Admin: adminAddress, + SubnetID: l1.SubnetID, + ChurnPeriodSeconds: uint64(0), + MaximumChurnPercentage: uint8(20), + }, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} + +func DeployAndInitializeValidatorManagerSpecialization( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + validatorManagerAddress common.Address, + managerType ValidatorManagerConcreteType, + proxy bool, +) (common.Address, *proxyadmin.ProxyAdmin) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + var ( + tx *types.Transaction + address common.Address + proxyAdmin *proxyadmin.ProxyAdmin + ) + switch managerType { + case ERC20TokenStakingManager: + // Reset the global binary data for better test isolation + erc20tokenstakingmanager.ERC20TokenStakingManagerBin = erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.Bin + + var manager *erc20tokenstakingmanager.ERC20TokenStakingManager + address, tx, manager, err = erc20tokenstakingmanager.DeployERC20TokenStakingManager( + opts, + l1.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + if proxy { + // Overwrite the manager address with the proxy address + address, proxyAdmin = DeployTransparentUpgradeableProxy( + ctx, + l1, + senderKey, + address, + ) + manager, err = erc20tokenstakingmanager.NewERC20TokenStakingManager(address, l1.RPCClient) + Expect(err).Should(BeNil()) + } + + erc20Address, _ := DeployExampleERC20(ctx, senderKey, l1) + rewardCalculatorAddress, _ := DeployExampleRewardCalculator( + ctx, + senderKey, + l1, + uint64(10), + ) + + tx, err = manager.Initialize( + opts, + erc20tokenstakingmanager.StakingManagerSettings{ + Manager: validatorManagerAddress, + MinimumStakeAmount: big.NewInt(0).SetUint64(DefaultMinStakeAmount), + MaximumStakeAmount: big.NewInt(0).SetUint64(DefaultMaxStakeAmount), + MinimumStakeDuration: DefaultMinStakeDurationSeconds, + MinimumDelegationFeeBips: DefaultMinDelegateFeeBips, + MaximumStakeMultiplier: DefaultMaxStakeMultiplier, + WeightToValueFactor: big.NewInt(0).SetUint64(DefaultWeightToValueFactor), + RewardCalculator: rewardCalculatorAddress, + UptimeBlockchainID: l1.BlockchainID, + }, + erc20Address, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + case NativeTokenStakingManager: + // Reset the global binary data for better test isolation + nativetokenstakingmanager.NativeTokenStakingManagerBin = + nativetokenstakingmanager.NativeTokenStakingManagerMetaData.Bin + + var manager *nativetokenstakingmanager.NativeTokenStakingManager + address, tx, manager, err = nativetokenstakingmanager.DeployNativeTokenStakingManager( + opts, + l1.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + if proxy { + // Overwrite the manager address with the proxy address + address, proxyAdmin = DeployTransparentUpgradeableProxy( + ctx, + l1, + senderKey, + address, + ) + manager, err = nativetokenstakingmanager.NewNativeTokenStakingManager(address, l1.RPCClient) + Expect(err).Should(BeNil()) + } + + rewardCalculatorAddress, _ := DeployExampleRewardCalculator( + ctx, + senderKey, + l1, + uint64(10), + ) + + Expect(err).Should(BeNil()) + tx, err = manager.Initialize( + opts, + nativetokenstakingmanager.StakingManagerSettings{ + Manager: validatorManagerAddress, + MinimumStakeAmount: big.NewInt(0).SetUint64(DefaultMinStakeAmount), + MaximumStakeAmount: big.NewInt(0).SetUint64(DefaultMaxStakeAmount), + MinimumStakeDuration: DefaultMinStakeDurationSeconds, + MinimumDelegationFeeBips: DefaultMinDelegateFeeBips, + MaximumStakeMultiplier: DefaultMaxStakeMultiplier, + WeightToValueFactor: big.NewInt(0).SetUint64(DefaultWeightToValueFactor), + RewardCalculator: rewardCalculatorAddress, + UptimeBlockchainID: l1.BlockchainID, + }, + ) + Expect(err).Should(BeNil()) + case PoAValidatorManager: + Expect(proxy).Should(BeFalse(), "PoAValidatorManager is not upgradeable") + + poamanager.PoAManagerBin = poamanager.PoAManagerMetaData.Bin + + address, tx, _, err = poamanager.DeployPoAManager( + opts, + l1.RPCClient, + crypto.PubkeyToAddress(senderKey.PublicKey), + validatorManagerAddress, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + } + return address, proxyAdmin +} + +func DeployExampleRewardCalculator( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + rewardBasisPoints uint64, +) (common.Address, *examplerewardcalculator.ExampleRewardCalculator) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, calculator, err := examplerewardcalculator.DeployExampleRewardCalculator( + opts, + l1.RPCClient, + rewardBasisPoints, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, l1, tx.Hash()) + + return address, calculator +} + +// +// Validator Set Initialization utils +// + +func InitializeValidatorSet( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + validatorManagerAddress common.Address, + networkID uint32, + signatureAggregator *SignatureAggregator, + nodes []Node, +) []ids.ID { + log.Println("Initializing validator set", "subnetID", l1Info.SubnetID) + initialValidators := make([]warpMessage.SubnetToL1ConversionValidatorData, len(nodes)) + initialValidatorsABI := make([]acp99manager.InitialValidator, len(nodes)) + for i, node := range nodes { + initialValidators[i] = warpMessage.SubnetToL1ConversionValidatorData{ + NodeID: node.NodeID.Bytes(), + BLSPublicKey: node.NodePoP.PublicKey, + Weight: nodes[i].Weight, + } + initialValidatorsABI[i] = acp99manager.InitialValidator{ + NodeID: node.NodeID.Bytes(), + BlsPublicKey: node.NodePoP.PublicKey[:], + Weight: nodes[i].Weight, + } + } + + l1ConversionData := warpMessage.SubnetToL1ConversionData{ + SubnetID: l1Info.SubnetID, + ManagerChainID: l1Info.BlockchainID, + ManagerAddress: validatorManagerAddress[:], + Validators: initialValidators, + } + l1ConversionDataABI := acp99manager.ConversionData{ + SubnetID: l1Info.SubnetID, + ValidatorManagerBlockchainID: l1Info.BlockchainID, + ValidatorManagerAddress: validatorManagerAddress, + InitialValidators: initialValidatorsABI, + } + l1ConversionID, err := warpMessage.SubnetToL1ConversionID(l1ConversionData) + Expect(err).Should(BeNil()) + l1ConversionSignedMessage := ConstructL1ConversionMessage( + l1ConversionID, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt := DeliverL1Conversion( + ctx, + senderKey, + l1Info, + validatorManagerAddress, + l1ConversionSignedMessage, + l1ConversionDataABI, + ) + manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + + // Check that the first initial validator was registered successfully + initialValidatorCreatedEvent, err := GetEventFromLogs( + receipt.Logs, + manager.ParseRegisteredInitialValidator, + ) + Expect(err).Should(BeNil()) + Expect(ids.NodeID(initialValidatorCreatedEvent.NodeID)).Should(Equal(nodes[0].NodeID)) + var validationIDs []ids.ID + for i := range nodes { + validationIDs = append(validationIDs, l1Info.SubnetID.Append(uint32(i))) + } + + Expect(initialValidatorCreatedEvent.Weight).Should(Equal(nodes[0].Weight)) + + emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) + Expect(emittedValidationID).Should(Equal(validationIDs[0])) + + return validationIDs +} + +func DeliverL1Conversion( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + validatorManagerAddress common.Address, + l1ConversionSignedMessage *avalancheWarp.Message, + l1ConversionData acp99manager.ConversionData, +) *types.Receipt { + abi, err := acp99manager.ACP99ManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("initializeValidatorSet", l1ConversionData, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + senderKey, + l1, + validatorManagerAddress, + l1ConversionSignedMessage.Bytes(), + ) +} + +// +// Function call utils +// + +func InitiateNativeValidatorRegistration( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakeAmount *big.Int, + node Node, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + validatorManagerAddress common.Address, +) (*types.Receipt, *acp99manager.ACP99ManagerInitiatedValidatorRegistration) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = stakeAmount + + tx, err := stakingManager.InitiateValidatorRegistration( + opts, + node.NodeID[:], + node.NodePoP.PublicKey[:], + nativetokenstakingmanager.PChainOwner{}, + nativetokenstakingmanager.PChainOwner{}, + DefaultMinDelegateFeeBips, + DefaultMinStakeDurationSeconds, + common.HexToAddress(DefaultRewardRecipientAddress), + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1.RPCClient) + Expect(err).Should(BeNil()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseInitiatedValidatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(ids.NodeID(registrationInitiatedEvent.NodeID)).Should(Equal(node.NodeID)) + return receipt, registrationInitiatedEvent +} + +func InitiateERC20ValidatorRegistration( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakeAmount *big.Int, + token *exampleerc20.ExampleERC20, + stakingManagerAddress common.Address, + node Node, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + validatorManagerAddress common.Address, +) (*types.Receipt, *acp99manager.ACP99ManagerInitiatedValidatorRegistration) { + ERC20Approve( + ctx, + token, + stakingManagerAddress, + stakeAmount, + l1, + senderKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := stakingManager.InitiateValidatorRegistration( + opts, + node.NodeID[:], + node.NodePoP.PublicKey[:], + erc20tokenstakingmanager.PChainOwner{}, + erc20tokenstakingmanager.PChainOwner{}, + DefaultMinDelegateFeeBips, + DefaultMinStakeDurationSeconds, + stakeAmount, + common.HexToAddress(DefaultRewardRecipientAddress), + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1.RPCClient) + Expect(err).Should(BeNil()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseInitiatedValidatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(ids.NodeID(registrationInitiatedEvent.NodeID)).Should(Equal(node.NodeID)) + return receipt, registrationInitiatedEvent +} + +func InitiatePoAValidatorRegistration( + ctx context.Context, + ownerKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + node Node, + validatorManager *poamanager.PoAManager, + validatorManagerAddress common.Address, +) (*types.Receipt, *acp99manager.ACP99ManagerInitiatedValidatorRegistration) { + opts, err := bind.NewKeyedTransactorWithChainID(ownerKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := validatorManager.InitiateValidatorRegistration( + opts, + node.NodeID[:], + node.NodePoP.PublicKey[:], + poamanager.PChainOwner{}, + poamanager.PChainOwner{}, + node.Weight, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1.RPCClient) + Expect(err).Should(BeNil()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseInitiatedValidatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(ids.NodeID(registrationInitiatedEvent.NodeID)).Should(Equal(node.NodeID)) + return receipt, registrationInitiatedEvent +} + +func CompleteValidatorRegistration( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakingManagerAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := acp99manager.ACP99ManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeValidatorRegistration", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + senderKey, + l1, + stakingManagerAddress, + registrationSignedMessage.Bytes(), + ) +} + +// Calls a method that retreived a signed Warp message from the transaction's access list +func CallWarpReceiver( + ctx context.Context, + callData []byte, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + contract common.Address, + signedMessageBytes []byte, +) *types.Receipt { + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, l1, PrivateKeyToAddress(senderKey)) + + registrationTx := types.NewTx(&types.DynamicFeeTx{ + ChainID: l1.EVMChainID, + Nonce: nonce, + To: &contract, + Gas: 2_000_000, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: common.Big0, + Data: callData, + AccessList: types.AccessList{ + { + Address: warp.ContractAddress, + StorageKeys: predicate.New(signedMessageBytes), + }, + }, + }) + + signedRegistrationTx := SignTransaction(registrationTx, senderKey, l1.EVMChainID) + return SendTransactionAndWaitForSuccess(ctx, l1, signedRegistrationTx) +} + +func InitiateAndCompleteNativeValidatorRegistration( + ctx context.Context, + signatureAggregator *SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + stakingManagerAddress common.Address, + validatorManagerAddress common.Address, + node Node, + pchainWallet pwallet.Wallet, + networkID uint32, +) *acp99manager.ACP99ManagerInitiatedValidatorRegistration { + stakeAmount, err := stakingManager.WeightToValue( + &bind.CallOpts{}, + node.Weight, + ) + Expect(err).Should(BeNil()) + // Initiate validator registration + receipt, registrationInitiatedEvent := InitiateNativeValidatorRegistration( + ctx, + fundedKey, + l1Info, + stakeAmount, + node, + stakingManager, + validatorManagerAddress, + ) + validationID := registrationInitiatedEvent.ValidationID + + // Gather subnet-evm Warp signatures for the RegisterL1ValidatorMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, l1Info, pChainInfo, nil, signatureAggregator) + + _, err = pchainWallet.IssueRegisterL1ValidatorTx( + 100*units.Avax, + node.NodePoP.ProofOfPossession, + signedWarpMessage.Bytes(), + ) + Expect(err).Should(BeNil()) + PChainProposerVMWorkaround(pchainWallet) + AdvanceProposerVM(ctx, l1Info, fundedKey, 5) + + // Construct a L1ValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator registration") + registrationSignedMessage := ConstructL1ValidatorRegistrationMessage( + validationID, + registrationInitiatedEvent.RegistrationExpiry, + node, + true, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt = CompleteValidatorRegistration( + ctx, + fundedKey, + l1Info, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseCompletedValidatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + + return registrationInitiatedEvent +} + +func InitiateAndCompleteERC20ValidatorRegistration( + ctx context.Context, + signatureAggregator *SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + stakingManagerAddress common.Address, + validatorManagerAddress common.Address, + erc20 *exampleerc20.ExampleERC20, + node Node, + pchainWallet pwallet.Wallet, + networkID uint32, +) *acp99manager.ACP99ManagerInitiatedValidatorRegistration { + stakeAmount, err := stakingManager.WeightToValue( + &bind.CallOpts{}, + node.Weight, + ) + Expect(err).Should(BeNil()) + // Initiate validator registration + var receipt *types.Receipt + log.Println("Initializing validator registration") + receipt, registrationInitiatedEvent := InitiateERC20ValidatorRegistration( + ctx, + fundedKey, + l1Info, + stakeAmount, + erc20, + stakingManagerAddress, + node, + stakingManager, + validatorManagerAddress, + ) + validationID := registrationInitiatedEvent.ValidationID + + // Gather subnet-evm Warp signatures for the RegisterL1ValidatorMessage & relay to the P-Chain + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, l1Info, pChainInfo, nil, signatureAggregator) + + _, err = pchainWallet.IssueRegisterL1ValidatorTx( + 100*units.Avax, + node.NodePoP.ProofOfPossession, + signedWarpMessage.Bytes(), + ) + Expect(err).Should(BeNil()) + PChainProposerVMWorkaround(pchainWallet) + AdvanceProposerVM(ctx, l1Info, fundedKey, 5) + + // Construct a L1ValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator registration") + registrationSignedMessage := ConstructL1ValidatorRegistrationMessage( + validationID, + registrationInitiatedEvent.RegistrationExpiry, + node, + true, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt = CompleteValidatorRegistration( + ctx, + fundedKey, + l1Info, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseCompletedValidatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + + return registrationInitiatedEvent +} + +func InitiateAndCompletePoAValidatorRegistration( + ctx context.Context, + signatureAggregator *SignatureAggregator, + ownerKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + poaManager *poamanager.PoAManager, + poaManagerAddress common.Address, + validatorManagerAddress common.Address, + expiry uint64, + node Node, + pchainWallet pwallet.Wallet, + networkID uint32, +) *acp99manager.ACP99ManagerInitiatedValidatorRegistration { + // Initiate validator registration + receipt, registrationInitiatedEvent := InitiatePoAValidatorRegistration( + ctx, + ownerKey, + l1Info, + node, + poaManager, + poaManagerAddress, + ) + validationID := registrationInitiatedEvent.ValidationID + + // Gather subnet-evm Warp signatures for the RegisterL1ValidatorMessage & relay to the P-Chain + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, l1Info, pChainInfo, nil, signatureAggregator) + + _, err := pchainWallet.IssueRegisterL1ValidatorTx( + 100*units.Avax, + node.NodePoP.ProofOfPossession, + signedWarpMessage.Bytes(), + ) + Expect(err).Should(BeNil()) + PChainProposerVMWorkaround(pchainWallet) + AdvanceProposerVM(ctx, l1Info, ownerKey, 5) + + // Construct a L1ValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator registration") + registrationSignedMessage := ConstructL1ValidatorRegistrationMessage( + validationID, + expiry, + node, + true, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt = CompleteValidatorRegistration( + ctx, + ownerKey, + l1Info, + poaManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseCompletedValidatorRegistration, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + + return registrationInitiatedEvent +} + +func InitiateEndPoSValidation( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakingManager *istakingmanager.IStakingManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.InitiateValidatorRemoval( + opts, + validationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} + +func ForceInitiateEndPoSValidation( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakingManager *istakingmanager.IStakingManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.ForceInitiateValidatorRemoval( + opts, + validationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} + +func ConstructUptimeProofMessage( + validationID ids.ID, + uptime uint64, + l1 interfaces.L1TestInfo, + networkID uint32, + signatureAggregator *SignatureAggregator, +) *avalancheWarp.Message { + uptimePayload, err := messages.NewValidatorUptime(validationID, uptime) + Expect(err).Should(BeNil()) + addressedCall, err := warpPayload.NewAddressedCall(nil, uptimePayload.Bytes()) + Expect(err).Should(BeNil()) + uptimeProofUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + l1.BlockchainID, + addressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + uptimeProofSignedMessage, err := signatureAggregator.CreateSignedMessage( + uptimeProofUnsignedMessage, + nil, + l1.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + return uptimeProofSignedMessage +} + +func ForceInitiateEndPoSValidationWithUptime( + ctx context.Context, + networkID uint32, + signatureAggregator *SignatureAggregator, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakingManagerAddress common.Address, + validationID ids.ID, + uptime uint64, +) *types.Receipt { + uptimeMsg := ConstructUptimeProofMessage( + validationID, + uptime, + l1, + networkID, + signatureAggregator, + ) + + abi, err := istakingmanager.IStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("forceInitiateValidatorRemoval", validationID, true, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + senderKey, + l1, + stakingManagerAddress, + uptimeMsg.Bytes(), + ) +} + +func InitiateEndPoSValidationWithUptime( + ctx context.Context, + networkID uint32, + signatureAggregator *SignatureAggregator, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakingManagerAddress common.Address, + validationID ids.ID, + uptime uint64, +) *types.Receipt { + uptimeMsg := ConstructUptimeProofMessage( + validationID, + uptime, + l1, + networkID, + signatureAggregator, + ) + + abi, err := istakingmanager.IStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("initiateValidatorRemoval", validationID, true, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + senderKey, + l1, + stakingManagerAddress, + uptimeMsg.Bytes(), + ) +} + +func InitiateEndPoAValidation( + ctx context.Context, + ownerKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + validatorManager *poamanager.PoAManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(ownerKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := validatorManager.InitiateValidatorRemoval( + opts, + validationID, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} + +func CompleteEndPoAValidation( + ctx context.Context, + ownerKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + poaAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := validatormanager.ValidatorManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeValidatorRemoval", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + ownerKey, + l1, + poaAddress, + registrationSignedMessage.Bytes(), + ) +} + +func CompleteEndPoSValidation( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + posAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := istakingmanager.IStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeValidatorRemoval", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + senderKey, + l1, + posAddress, + registrationSignedMessage.Bytes(), + ) +} + +func InitiateERC20DelegatorRegistration( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + validationID ids.ID, + delegationAmount *big.Int, + token *exampleerc20.ExampleERC20, + stakingManagerAddress common.Address, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, +) *types.Receipt { + ERC20Approve( + ctx, + token, + stakingManagerAddress, + delegationAmount, + l1, + senderKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := stakingManager.InitiateDelegatorRegistration( + opts, + validationID, + delegationAmount, + common.HexToAddress(DefaultRewardRecipientAddress), + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + _, err = GetEventFromLogs( + receipt.Logs, + stakingManager.ParseInitiatedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + return receipt +} + +func InitiateNativeDelegatorRegistration( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + validationID ids.ID, + delegationAmount *big.Int, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = delegationAmount + + tx, err := stakingManager.InitiateDelegatorRegistration( + opts, + validationID, + common.HexToAddress(DefaultRewardRecipientAddress), + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, l1, tx.Hash()) + _, err = GetEventFromLogs( + receipt.Logs, + stakingManager.ParseInitiatedDelegatorRegistration, + ) + Expect(err).Should(BeNil()) + return receipt +} + +func CompleteDelegatorRegistration( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + delegationID ids.ID, + l1 interfaces.L1TestInfo, + stakingManagerAddress common.Address, + signedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := istakingmanager.IStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeDelegatorRegistration", delegationID, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + senderKey, + l1, + stakingManagerAddress, + signedMessage.Bytes(), + ) +} + +func InitiateDelegatorRemoval( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + l1 interfaces.L1TestInfo, + stakingManagerAddress common.Address, + delegationID ids.ID, +) *types.Receipt { + stakingManager, err := istakingmanager.NewIStakingManager(stakingManagerAddress, l1.RPCClient) + Expect(err).Should(BeNil()) + WaitMinStakeDuration(ctx, l1, senderKey) + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, l1.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.ForceInitiateDelegatorRemoval( + opts, + delegationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(ctx, l1, tx.Hash()) +} + +func CompleteDelegatorRemoval( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + delegationID ids.ID, + l1 interfaces.L1TestInfo, + stakingManagerAddress common.Address, + signedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := istakingmanager.IStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeDelegatorRemoval", delegationID, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + ctx, + callData, + senderKey, + l1, + stakingManagerAddress, + signedMessage.Bytes(), + ) +} + +func InitiateAndCompleteEndInitialPoSValidation( + ctx context.Context, + signatureAggregator *SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + stakingManager *istakingmanager.IStakingManager, + stakingManagerAddress common.Address, + validatorManagerAddress common.Address, + validationID ids.ID, + index uint32, + weight uint64, + pchainWallet pwallet.Wallet, + networkID uint32, +) { + log.Println("Initializing initial validator removal") + WaitMinStakeDuration(ctx, l1Info, fundedKey) + receipt := ForceInitiateEndPoSValidation( + ctx, + fundedKey, + l1Info, + stakingManager, + validationID, + ) + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseInitiatedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetL1ValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, l1Info) + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedMessage, + nil, + l1Info.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + + // Deliver the Warp message to the P-Chain + pchainWallet.IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + PChainProposerVMWorkaround(pchainWallet) + AdvanceProposerVM(ctx, l1Info, fundedKey, 5) + + // Construct a L1ValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing initial validator removal") + registrationSignedMessage := ConstructL1ValidatorRegistrationMessageForInitialValidator( + validationID, + index, + false, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt = CompleteEndPoSValidation( + ctx, + fundedKey, + l1Info, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + validationEndedEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseCompletedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(validationEndedEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +func InitiateAndCompleteEndPoSValidation( + ctx context.Context, + signatureAggregator *SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + stakingManager *istakingmanager.IStakingManager, + stakingManagerAddress common.Address, + validatorManagerAddress common.Address, + validationID ids.ID, + expiry uint64, + node Node, + nonce uint64, + includeUptime bool, + validatorStartTime time.Time, + pchainWallet pwallet.Wallet, + networkID uint32, +) { + log.Println("Initializing validator removal") + WaitMinStakeDuration(ctx, l1Info, fundedKey) + + var receipt *types.Receipt + if includeUptime { + uptime := uint64(time.Since(validatorStartTime).Seconds()) + receipt = ForceInitiateEndPoSValidationWithUptime( + ctx, + networkID, + signatureAggregator, + fundedKey, + l1Info, + stakingManagerAddress, + validationID, + uptime, + ) + } else { + receipt = ForceInitiateEndPoSValidation( + ctx, + fundedKey, + l1Info, + stakingManager, + validationID, + ) + } + + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseInitiatedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight).Should(Equal(node.Weight)) + + // Gather subnet-evm Warp signatures for the SetL1ValidatorWeightMessage & relay to the P-Chain + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, l1Info) + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedMessage, + nil, + l1Info.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + + // Deliver the Warp message to the P-Chain + pchainWallet.IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + PChainProposerVMWorkaround(pchainWallet) + AdvanceProposerVM(ctx, l1Info, fundedKey, 5) + + // Construct a L1ValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing validator removal") + registrationSignedMessage := ConstructL1ValidatorRegistrationMessage( + validationID, + expiry, + node, + false, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt = CompleteEndPoSValidation( + ctx, + fundedKey, + l1Info, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseCompletedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +func InitiateAndCompleteEndInitialPoAValidation( + ctx context.Context, + signatureAggregator *SignatureAggregator, + ownerKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + poaManager *poamanager.PoAManager, + poaManagerAddress common.Address, + validatorManagerAddress common.Address, + validationID ids.ID, + index uint32, + weight uint64, + pchainWallet pwallet.Wallet, + networkID uint32, +) { + log.Println("Initializing initial validator removal") + WaitMinStakeDuration(ctx, l1Info, ownerKey) + receipt := InitiateEndPoAValidation( + ctx, + ownerKey, + l1Info, + poaManager, + validationID, + ) + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseInitiatedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetL1ValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + unsignedMessage := ExtractWarpMessageFromLog(ctx, receipt, l1Info) + signedWarpMessage, err := signatureAggregator.CreateSignedMessage( + unsignedMessage, + nil, + l1Info.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + + // Deliver the Warp message to the P-Chain + pchainWallet.IssueSetL1ValidatorWeightTx(signedWarpMessage.Bytes()) + PChainProposerVMWorkaround(pchainWallet) + AdvanceProposerVM(ctx, l1Info, ownerKey, 5) + + // Construct a L1ValidatorRegistrationMessage Warp message from the P-Chain + log.Println("Completing initial validator removal") + registrationSignedMessage := ConstructL1ValidatorRegistrationMessageForInitialValidator( + validationID, + index, + false, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt = CompleteEndPoAValidation( + ctx, + ownerKey, + l1Info, + poaManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + validationEndedEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseCompletedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(validationEndedEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +func InitiateAndCompleteEndPoAValidation( + ctx context.Context, + signatureAggregator *SignatureAggregator, + ownerKey *ecdsa.PrivateKey, + l1Info interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + poaManager *poamanager.PoAManager, + poaManagerAddress common.Address, + validatorManagerAddress common.Address, + validationID ids.ID, + weight uint64, + nonce uint64, + networkID uint32, +) { + receipt := InitiateEndPoAValidation( + ctx, + ownerKey, + l1Info, + poaManager, + validationID, + ) + acp99Manager, err := acp99manager.NewACP99Manager(validatorManagerAddress, l1Info.RPCClient) + Expect(err).Should(BeNil()) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseInitiatedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetL1ValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := ConstructSignedWarpMessage(ctx, receipt, l1Info, pChainInfo, nil, signatureAggregator) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + ValidateL1ValidatorWeightMessage(signedWarpMessage, validationID, 0, nonce) + + // Construct a L1ValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := ConstructL1ValidatorRegistrationMessage( + validationID, + 0, + Node{}, + false, + l1Info, + pChainInfo, + networkID, + signatureAggregator, + ) + + // Deliver the Warp message to the L1 + receipt = CompleteEndPoAValidation( + ctx, + ownerKey, + l1Info, + poaManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + acp99Manager.ParseCompletedValidatorRemoval, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +// +// P-Chain utils +// + +func ConstructL1ValidatorRegistrationMessageForInitialValidator( + validationID ids.ID, + index uint32, + valid bool, + l1 interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + networkID uint32, + signatureAggregator *SignatureAggregator, +) *avalancheWarp.Message { + justification := platformvm.L1ValidatorRegistrationJustification{ + Preimage: &platformvm.L1ValidatorRegistrationJustification_ConvertSubnetToL1TxData{ + ConvertSubnetToL1TxData: &platformvm.SubnetIDIndex{ + SubnetId: l1.SubnetID[:], + Index: index, + }, + }, + } + justificationBytes, err := proto.Marshal(&justification) + Expect(err).Should(BeNil()) + + registrationPayload, err := warpMessage.NewL1ValidatorRegistration(validationID, valid) + Expect(err).Should(BeNil()) + registrationAddressedCall, err := warpPayload.NewAddressedCall(nil, registrationPayload.Bytes()) + Expect(err).Should(BeNil()) + registrationUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + pChainInfo.BlockchainID, + registrationAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + registrationSignedMessage, err := signatureAggregator.CreateSignedMessage( + registrationUnsignedMessage, + justificationBytes, + l1.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + + return registrationSignedMessage +} + +func ConstructL1ValidatorRegistrationMessage( + validationID ids.ID, + expiry uint64, + node Node, + valid bool, + l1 interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + networkID uint32, + signatureAggregator *SignatureAggregator, +) *avalancheWarp.Message { + msg, err := warpMessage.NewRegisterL1Validator( + l1.SubnetID, + node.NodeID, + node.NodePoP.PublicKey, + expiry, + warpMessage.PChainOwner{}, + warpMessage.PChainOwner{}, + node.Weight, + ) + Expect(err).Should(BeNil()) + justification := platformvm.L1ValidatorRegistrationJustification{ + Preimage: &platformvm.L1ValidatorRegistrationJustification_RegisterL1ValidatorMessage{ + RegisterL1ValidatorMessage: msg.Bytes(), + }, + } + justificationBytes, err := proto.Marshal(&justification) + Expect(err).Should(BeNil()) + + registrationPayload, err := warpMessage.NewL1ValidatorRegistration(validationID, valid) + Expect(err).Should(BeNil()) + registrationAddressedCall, err := warpPayload.NewAddressedCall(nil, registrationPayload.Bytes()) + Expect(err).Should(BeNil()) + registrationUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + pChainInfo.BlockchainID, + registrationAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + registrationSignedMessage, err := signatureAggregator.CreateSignedMessage( + registrationUnsignedMessage, + justificationBytes, + l1.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + + return registrationSignedMessage +} + +func ConstructL1ValidatorWeightMessage( + validationID ids.ID, + nonce uint64, + weight uint64, + l1 interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + signatureAggregator *SignatureAggregator, + networkID uint32, +) *avalancheWarp.Message { + payload, err := warpMessage.NewL1ValidatorWeight(validationID, nonce, weight) + Expect(err).Should(BeNil()) + updateAddressedCall, err := warpPayload.NewAddressedCall(nil, payload.Bytes()) + Expect(err).Should(BeNil()) + updateUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + pChainInfo.BlockchainID, + updateAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + updateSignedMessage, err := signatureAggregator.CreateSignedMessage( + updateUnsignedMessage, + nil, + l1.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + return updateSignedMessage +} + +func ConstructL1ConversionMessage( + l1ConversionID ids.ID, + l1 interfaces.L1TestInfo, + pChainInfo interfaces.L1TestInfo, + networkID uint32, + signatureAggregator *SignatureAggregator, +) *avalancheWarp.Message { + l1ConversionPayload, err := warpMessage.NewSubnetToL1Conversion(l1ConversionID) + Expect(err).Should(BeNil()) + l1ConversionAddressedCall, err := warpPayload.NewAddressedCall( + nil, + l1ConversionPayload.Bytes(), + ) + Expect(err).Should(BeNil()) + l1ConversionUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + pChainInfo.BlockchainID, + l1ConversionAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + l1ConversionSignedMessage, err := signatureAggregator.CreateSignedMessage( + l1ConversionUnsignedMessage, + l1.SubnetID[:], + l1.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + return l1ConversionSignedMessage +} + +// +// Warp message validiation utils +// These will be replaced by the actual implementation on the P-Chain in the future +// + +func ValidateRegisterL1ValidatorMessage( + signedWarpMessage *avalancheWarp.Message, + nodeID ids.ID, + weight uint64, + subnetID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, +) { + // Validate the Warp message, (this will be done on the P-Chain in the future) + msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) + Expect(err).Should(BeNil()) + // Check that the addressed call payload is a registered Warp message type + var payloadInterface warpMessage.Payload + ver, err := warpMessage.Codec.Unmarshal(msg.Payload, &payloadInterface) + Expect(err).Should(BeNil()) + payload, ok := payloadInterface.(*warpMessage.RegisterL1Validator) + Expect(ok).Should(BeTrue()) + + Expect(ver).Should(Equal(uint16(warpMessage.CodecVersion))) + Expect(payload.NodeID).Should(Equal(nodeID)) + Expect(payload.Weight).Should(Equal(weight)) + Expect(payload.SubnetID).Should(Equal(subnetID)) + Expect(payload.BLSPublicKey[:]).Should(Equal(blsPublicKey[:])) +} + +func ValidateL1ValidatorWeightMessage( + signedWarpMessage *avalancheWarp.Message, + validationID ids.ID, + weight uint64, + nonce uint64, +) { + msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) + Expect(err).Should(BeNil()) + // Check that the addressed call payload is a registered Warp message type + var payloadInterface warpMessage.Payload + ver, err := warpMessage.Codec.Unmarshal(msg.Payload, &payloadInterface) + Expect(err).Should(BeNil()) + payload, ok := payloadInterface.(*warpMessage.L1ValidatorWeight) + Expect(ok).Should(BeTrue()) + + Expect(ver).Should(Equal(uint16(warpMessage.CodecVersion))) + Expect(payload.ValidationID).Should(Equal(validationID)) + Expect(payload.Weight).Should(Equal(weight)) + Expect(payload.Nonce).Should(Equal(nonce)) +} + +func WaitMinStakeDuration( + ctx context.Context, + l1 interfaces.L1TestInfo, + fundedKey *ecdsa.PrivateKey, +) { + // Make sure minimum stake duration has passed + time.Sleep(time.Duration(DefaultMinStakeDurationSeconds) * time.Second) + + // Send a loopback transaction to self to force a block production + // before delisting the validator. + SendNativeTransfer( + ctx, + l1, + fundedKey, + common.Address{}, + big.NewInt(10), + ) +} + +func CalculateL1ConversionValidationId(subnetID ids.ID, validatorIdx uint32) ids.ID { + preImage := make([]byte, 36) + copy(preImage[0:32], subnetID[:]) + binary.BigEndian.PutUint32(preImage[32:36], validatorIdx) + return sha256.Sum256(preImage) +} + +// PackSubnetConversionData defines a packing function that works +// over any struct instance of SubnetConversionData since the abi-bindings +// process generates one for each of the different contracts. +func PackSubnetConversionData(data interface{}) ([]byte, error) { + v := reflect.ValueOf(data) + if v.Kind() != reflect.Struct { + return nil, fmt.Errorf("expected struct, got %s", v.Kind()) + } + // Define required fields and their expected types + requiredFields := map[string]reflect.Type{ + "SubnetID": reflect.TypeOf([32]byte{}), + "ValidatorManagerBlockchainID": reflect.TypeOf([32]byte{}), + "ValidatorManagerAddress": reflect.TypeOf(common.Address{}), + // InitialValidators is a slice of structs and handled separately + "InitialValidators": reflect.TypeOf([]struct{}{}), + } + // Check for required fields and types + for fieldName, expectedType := range requiredFields { + field := v.FieldByName(fieldName) + + if !field.IsValid() { + return nil, fmt.Errorf("field %s is missing", fieldName) + } + // Allow flexible types for InitialValidators by checking it contains structs + if fieldName == "InitialValidators" { + if field.Kind() != reflect.Slice || field.Type().Elem().Kind() != reflect.Struct { + return nil, fmt.Errorf("field %s has incorrect type: expected a slice of structs", fieldName) + } + } else { + if field.Type() != expectedType { + return nil, fmt.Errorf("field %s has incorrect type: expected %s, got %s", fieldName, expectedType, field.Type()) + } + } + } + + subnetID := v.FieldByName("SubnetID").Interface().([32]byte) + validatorManagerBlockchainID := v.FieldByName("ValidatorManagerBlockchainID").Interface().([32]byte) + validatorManagerAddress := v.FieldByName("ValidatorManagerAddress").Interface().(common.Address) + initialValidators := v.FieldByName("InitialValidators") + + // Pack each InitialValidator struct + packedInitialValidators := make([][]byte, initialValidators.Len()) + var packedInitialValidatorsLen uint32 + for i := 0; i < initialValidators.Len(); i++ { + iv := initialValidators.Index(i).Interface() + ivPacked, err := PackInitialValidator(iv) + if err != nil { + return nil, fmt.Errorf("failed to pack InitialValidator: %w", err) + } + + packedInitialValidators[i] = ivPacked + packedInitialValidatorsLen += uint32(len(ivPacked)) + } + + b := make([]byte, 94+packedInitialValidatorsLen) + binary.BigEndian.PutUint16(b[0:2], uint16(warpMessage.CodecVersion)) + copy(b[2:34], subnetID[:]) + copy(b[34:66], validatorManagerBlockchainID[:]) + // These are evm addresses and have lengths of 20 so hardcoding here + binary.BigEndian.PutUint32(b[66:70], uint32(20)) + copy(b[70:90], validatorManagerAddress.Bytes()) + binary.BigEndian.PutUint32(b[90:94], uint32(initialValidators.Len())) + offset := 94 + for _, ivPacked := range packedInitialValidators { + copy(b[offset:offset+len(ivPacked)], ivPacked) + offset += len(ivPacked) + } + + return b, nil +} + +// PackInitialValidator defines a packing function that works +// over any struct instance of InitialValidator since the abi-bindings +// process generates one for each of the different contracts. +func PackInitialValidator(iv interface{}) ([]byte, error) { + v := reflect.ValueOf(iv) + + // Ensure the passed interface is a struct + if v.Kind() != reflect.Struct { + return nil, fmt.Errorf("expected a struct, got %s", v.Kind()) + } + + // Define required fields and their expected types + requiredFields := map[string]reflect.Type{ + "NodeID": reflect.TypeOf([]byte{}), + "Weight": reflect.TypeOf(uint64(0)), + "BlsPublicKey": reflect.TypeOf([]byte{}), + } + + // Check for required fields and types + for fieldName, expectedType := range requiredFields { + field := v.FieldByName(fieldName) + + if !field.IsValid() { + return nil, fmt.Errorf("field %s is missing", fieldName) + } + + if field.Type() != expectedType { + return nil, fmt.Errorf("field %s has incorrect type: expected %s, got %s", fieldName, expectedType, field.Type()) + } + } + + // At this point, we know the struct has all required fields with correct types + // Use reflection to retrieve field values and perform canonical packing + nodeID := v.FieldByName("NodeID").Interface().([]byte) + weight := v.FieldByName("Weight").Interface().(uint64) + blsPublicKey := v.FieldByName("BlsPublicKey").Interface().([]byte) + + b := make([]byte, 60+len(nodeID)) + binary.BigEndian.PutUint32(b[0:4], uint32(len(nodeID))) + copy(b[4:4+len(nodeID)], nodeID[:]) + binary.BigEndian.PutUint64(b[4+len(nodeID):4+len(nodeID)+8], weight) + copy(b[4+len(nodeID)+8:4+len(nodeID)+8+48], blsPublicKey) + return b, nil +} + +func PChainProposerVMWorkaround( + pchainWallet pwallet.Wallet, +) { + log.Println("Waiting for P-Chain...") + time.Sleep(30 * time.Second) +} + +func AdvanceProposerVM( + ctx context.Context, + l1 interfaces.L1TestInfo, + fundedKey *ecdsa.PrivateKey, + blocks int, +) { + log.Println("Advancing proposer VM") + for i := 0; i < blocks; i++ { + err := subnetEvmUtils.IssueTxsToActivateProposerVMFork( + ctx, l1.EVMChainID, fundedKey, l1.WSClient, + ) + Expect(err).Should(BeNil()) + } +} diff --git a/icm-contracts/tests/utils/warp-genesis-template.json b/icm-contracts/tests/utils/warp-genesis-template.json new file mode 100644 index 000000000..3ac111e02 --- /dev/null +++ b/icm-contracts/tests/utils/warp-genesis-template.json @@ -0,0 +1,92 @@ +{ + "config": { + "chainId": , + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "feeConfig": { + "gasLimit": 20000000, + "minBaseFee": 1000000000, + "targetGas": 100000000, + "baseFeeChangeDenominator": 48, + "minBlockGasCost": 0, + "maxBlockGasCost": 10000000, + "targetBlockRate": 2, + "blockGasCostStep": 500000 + }, + "warpConfig": { + "blockTimestamp": 1719343601, + "requirePrimaryNetworkSigners" : + }, + "contractNativeMinterConfig": { + "blockTimestamp": 0, + "adminAddresses": [ + "0xAcB633F5B00099c7ec187eB00156c5cd9D854b5B", + "0x3405506b3711859c5070949ed9b700c7ba7bf750", + "0x962c62B01529ecc0561D85d3fe395921ddC3665B", + "0x1549B96D9D97F435CA9b25000FEDE3A7e54C0bb9", + "0x190110D1228EB2cDd36559b2215A572Dc8592C3d", + "0xf9EF017A764F265A1fD0975bfc200725E41d860E", + "0x4f3663be6d22B0F19F8617f1A9E9485aB0144Bff", + "0x463a6bE7a5098A5f06435c6c468adD338F15B93A", + "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC" + ] + } + }, + "alloc": { + "": { + "balance": "0x0", + "code": "", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "nonce": 1 + }, + "": { + "balance": "0x0", + "nonce": 1 + }, + "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x1337cfd2dCff6270615B90938aCB1efE79801704": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0xFcec6c0674037f99fa473de09609B4b6D8158863": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x2e1533d976A675bCD6306deC3B05e9f73e6722Fb": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0xA638b0a597dc0520e2f20E83cFbeBBCd45a79990": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x787C079cB0d5A7AA1Cae95d991F76Dce771A432D": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x741D536f5B07bcD43727CD8435389CA36aE5A4Ae": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0xd466f12795BA59d0fef389c21fA63c287956fb18": { + "balance": "0x52B7D2DCC80CD2E4000000" + } + }, + "nonce": "0x0", + "timestamp": "0x667B19F0", + "extraData": "0x00", + "gasLimit": "0x1312D00", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } diff --git a/icm-contracts/utils/contract-deployment/README.md b/icm-contracts/utils/contract-deployment/README.md new file mode 100644 index 000000000..74263e859 --- /dev/null +++ b/icm-contracts/utils/contract-deployment/README.md @@ -0,0 +1,40 @@ +# TeleporterMessenger Contract Deployment + +The `TeleporterMessenger` contract is designed to only send and receive Avalanche ICM messages to and from its own address on different chains. We ensure that the contract can be deployed to the same address on every EVM based chain by using [Nick's Method](https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c). Only allowing messages to be sent and received by the same address guarantees that all messages use the same TeleporterMessenger message format because only the same exact contract bytecode could have been deployed to the same address. + +This directory contains scripts written in Golang to construct a raw transaction using Nick's method that deploys the TeleporterMessenger contract, and determine the keyless address that must be prefunded in order for the transaction to be sent. + +## Running + +There are two supporting subcommands: `constructKeylessTx` and `deriveContractAddress`. + +`go run utils/contract-deployment/contractDeploymentTools.go constructKeylessTx ` +OR +`go run utils/contract-deployment/contractDeploymentTools.go deriveContractAddress ` + +For example: +`go run utils/contract-deployment/contractDeploymentTools.go constructKeylessTx out/TeleporterMessenger.sol/TeleporterMessenger.json` +OR +`go run utils/contract-deployment/contractDeploymentTools.go deriveContractAddress 0x38545c4b331D8BFb3bee94C62D77a6735b5eF8c0 1` + +## Results + +The resulting raw transaction, `TeleporterMessenger` contract address, and universal deployer address are written to standard output, as well as to `UniversalTeleporterDeployerTransaction.txt`, `UniversalTeleporterMessengerContractAddress.txt`, and `UniversalTeleporterDeployerAddress.txt` respectively. + +## Deploy the contract + +Now that the keyless transaction is constructed, fund the deployer address. For example, using `cast`: + +```bash +teleporter_deployer_address=$(cat UniversalTeleporterDeployerAddress.txt) +cast send --private-key $my_private_key --value 10ether $teleporter_deployer_address --rpc-url $my_rpc_url +``` + +Then, deploy TeleporterMessenger by sending the keyless transaction: + +```bash +teleporter_deploy_tx=$(cat UniversalTeleporterDeployerTransaction.txt) +cast publish --rpc-url $my_rpc_url $teleporter_deploy_tx +``` + +Once you've verified that TeleporterMessenger was deployed to the address in `UniversalTeleporterMessengerContractAddress.txt`, TeleporterMessenger and ICM is ready to use. diff --git a/icm-contracts/utils/contract-deployment/contractDeploymentTools.go b/icm-contracts/utils/contract-deployment/contractDeploymentTools.go new file mode 100644 index 000000000..b052444e8 --- /dev/null +++ b/icm-contracts/utils/contract-deployment/contractDeploymentTools.go @@ -0,0 +1,54 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package main + +import ( + "fmt" + "log" + "os" + "strconv" + + deploymentUtils "github.com/ava-labs/icm-services/icm-contracts/utils/deployment-utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" +) + +func main() { + if len(os.Args) < 2 { + log.Panic("Invalid argument count. Must provide at least one argument to specify command type.") + } + commandType := os.Args[1] + + switch commandType { + case "constructKeylessTx": + // Get the byte code of the teleporter contract to be deployed. + if len(os.Args) != 3 { + log.Panic("Invalid argument count. Must provide JSON file containing contract bytecode.") + } + _, _, _, _, err := deploymentUtils.ConstructKeylessTransaction( + os.Args[2], + true, + deploymentUtils.GetDefaultContractCreationGasPrice(), + ) + if err != nil { + log.Panic("Failed to construct keyless transaction.", err) + } + case "deriveContractAddress": + // Get the byte code of the teleporter contract to be deployed. + if len(os.Args) != 4 { + log.Panic("Invalid argument count. Must provide address and nonce.") + } + + deployerAddress := common.HexToAddress(os.Args[2]) + nonce, err := strconv.ParseUint(os.Args[3], 10, 64) + if err != nil { + log.Panic("Failed to parse nonce as uint", err) + } + + resultAddress := crypto.CreateAddress(deployerAddress, nonce) + fmt.Println(resultAddress.Hex()) + default: + log.Panic("Invalid command type. Supported options are \"constructKeylessTx\" and \"deriveContractAddress\".") + } +} diff --git a/icm-contracts/utils/deployment-utils/deployment_utils.go b/icm-contracts/utils/deployment-utils/deployment_utils.go new file mode 100644 index 000000000..14ea503f6 --- /dev/null +++ b/icm-contracts/utils/deployment-utils/deployment_utils.go @@ -0,0 +1,172 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package utils + +import ( + "encoding/hex" + "encoding/json" + "io/fs" + "log" + "math/big" + "os" + "strings" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/pkg/errors" +) + +const ( + // Roughly 3,010,000 gas needed to deploy contract. Padded to account for possible additions + defaultContractCreationGasLimit = uint64(4000000) + + // R and S values to use in a keyless transaction signature. + // The values do not technically need to be the same when using Nick's method, but the AvalancheGo + // APIs by default only allow legacy transactions to be broadcast if they have the same R and S values, + // which is used as a heuristic to identify (and allow) Nick's method transactions. + rsValueHex = "3333333333333333333333333333333333333333333333333333333333333333" + contractCreationTxFileName = "UniversalTeleporterDeployerTransaction.txt" + contractCreationAddrFileName = "UniversalTeleporterDeployerAddress.txt" + universalContractAddressFileName = "UniversalTeleporterMessengerContractAddress.txt" +) + +var ( + vValue = big.NewInt( + 27, + ) // Must be less than 35 to be considered non-EIP155 + defaultContractCreationGasPrice = big.NewInt(2500e9) // 2500 nAVAX/gas +) + +type byteCodeObj struct { + Object string `json:"object"` +} + +type byteCodeFile struct { + ByteCode byteCodeObj `json:"bytecode"` + DeployedByteCode byteCodeObj `json:"deployedBytecode"` +} + +func extractByteCode(byteCodeFileName string) (byteCodeFile, error) { + log.Println("Using bytecode file at", byteCodeFileName) + byteCodeFileContents, err := os.ReadFile(byteCodeFileName) + if err != nil { + return byteCodeFile{}, errors.Wrap(err, "Failed to read bytecode file contents") + } + var byteCodeJSON byteCodeFile + err = json.Unmarshal(byteCodeFileContents, &byteCodeJSON) + if err != nil { + return byteCodeFile{}, errors.Wrap(err, "Failed to unmarshal bytecode file contents as JSON") + } + return byteCodeJSON, nil +} + +// Constructs a keyless transaction using Nick's method +// Optionally writes the transaction, deployer address, and contract address to file +// Returns the transaction bytes, deployer address, and contract address +func ConstructKeylessTransaction( + byteCodeFileName string, + writeFile bool, + contractCreationGasPrice *big.Int, +) ([]byte, string, common.Address, common.Address, error) { + // Convert the R and S values (which must be the same) from hex. + rsValue, ok := new(big.Int).SetString(rsValueHex, 16) + if !ok { + return nil, "", common.Address{}, common.Address{}, errors.New( + "Failed to convert R and S value to big.Int.", + ) + } + + byteCodeFile, err := extractByteCode(byteCodeFileName) + if err != nil { + return nil, "", common.Address{}, common.Address{}, err + } + + // Parse the raw bytecode to be included in the deployment transaction. + byteCode, err := hex.DecodeString(strings.TrimPrefix(byteCodeFile.ByteCode.Object, "0x")) + if err != nil { + return nil, "", common.Address{}, common.Address{}, err + } + + // Construct the legacy transaction with pre-determined signature values. + contractCreationTx := types.NewTx(&types.LegacyTx{ + Nonce: 0, + Gas: defaultContractCreationGasLimit, + GasPrice: contractCreationGasPrice, + To: nil, // Contract creation transaction + Value: big.NewInt(0), + Data: byteCode, + V: vValue, + R: rsValue, + S: rsValue, + }) + + // Recover the "sender" address of the transaction. + senderAddress, err := types.HomesteadSigner{}.Sender(contractCreationTx) + if err != nil { + return nil, "", common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to recover the sender address of transaction", + ) + } + + // Serialize the raw transaction and sender address. + contractCreationTxBytes, err := contractCreationTx.MarshalBinary() + if err != nil { + return nil, "", common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to serialize raw transaction", + ) + } + contractCreationTxString := "0x" + hex.EncodeToString(contractCreationTxBytes) + senderAddressString := senderAddress.Hex() // "0x" prepended by Hex() already. + + // Derive the resulting contract address given that it will be deployed from the sender address using the nonce of 0. + contractAddress := crypto.CreateAddress(senderAddress, 0) + contractAddressString := contractAddress.Hex() // "0x" prepended by Hex() already. + + log.Println("TeleporterMessenger Keyless Deployer Address: ", senderAddressString) + log.Println("TeleporterMessenger Universal Contract Address: ", contractAddressString) + + if writeFile { + err = os.WriteFile( + contractCreationTxFileName, + []byte(contractCreationTxString), + fs.ModePerm, + ) + if err != nil { + return nil, "", common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to write to contract creation tx file", + ) + } + + err = os.WriteFile(contractCreationAddrFileName, []byte(senderAddressString), fs.ModePerm) + if err != nil { + return nil, "", common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to write to deployer address file", + ) + } + + err = os.WriteFile( + universalContractAddressFileName, + []byte(contractAddressString), + fs.ModePerm, + ) + if err != nil { + return nil, "", common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to write to contract address", + ) + } + } + return contractCreationTxBytes, byteCodeFile.DeployedByteCode.Object, senderAddress, contractAddress, nil +} + +func GetDefaultContractCreationGasPrice() *big.Int { + gasPrice := big.NewInt(0) + gasPrice.Set(defaultContractCreationGasPrice) + return gasPrice +} diff --git a/icm-contracts/utils/deployment-utils/deployment_utils_test.go b/icm-contracts/utils/deployment-utils/deployment_utils_test.go new file mode 100644 index 000000000..24225b0f6 --- /dev/null +++ b/icm-contracts/utils/deployment-utils/deployment_utils_test.go @@ -0,0 +1,23 @@ +package utils + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetDefaultContractCreationGasPrice(t *testing.T) { + gasPrice := GetDefaultContractCreationGasPrice() + require.Equal(t, defaultContractCreationGasPrice, gasPrice) + + // Ensure the function returns a copy of the default gas price. + gasPrice.Add(gasPrice, big.NewInt(1)) + require.NotEqual(t, defaultContractCreationGasPrice, gasPrice) + + // Ensure if the default gas price is changed, the function returns the new value. + newDefaultGasPrice := big.NewInt(1234) + defaultContractCreationGasPrice = newDefaultGasPrice + gasPrice = GetDefaultContractCreationGasPrice() + require.Equal(t, newDefaultGasPrice, gasPrice) +} diff --git a/icm-contracts/utils/gas-utils/gas_utils.go b/icm-contracts/utils/gas-utils/gas_utils.go new file mode 100644 index 000000000..61d36f28f --- /dev/null +++ b/icm-contracts/utils/gas-utils/gas_utils.go @@ -0,0 +1,86 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package utils + +import ( + "errors" + "math/big" + "time" + + "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + "github.com/ava-labs/subnet-evm/precompile/precompileconfig" +) + +const ( + MarkMessageReceiptGasCost uint64 = 2500 + DecodeMessageGasCostPerByte uint64 = 35 + TeleporterOverheadGasCost uint64 = 250_000 + + BaseFeeFactor = 2 + MaxPriorityFeePerGas = 2500000000 // 2.5 gwei +) + +var _ precompileconfig.Rules = &UpgradeRules{} + +type UpgradeRules struct { + UpgradeConfig upgrade.Config +} + +func (u *UpgradeRules) IsGraniteActivated() bool { + return u.UpgradeConfig.IsGraniteActivated(time.Now()) +} + +// CalculateReceiveMessageGasLimit calculates the estimated gas amount used by a single call +// to Teleporter receiveCrossChainMessage for the given message and validator bit vector. The result amount +// depends on the following: +// - Required gas limit for the message execution +// - The size of the Warp message +// - The size of the Teleporter message included in the Warp message +// - The number of Teleporter receipts +// - Base gas cost for {receiveCrossChainMessage} call +// - The number of validator signatures included in the aggregate signature +// TODO: Benchmark to confirm that gas limits estimates are accurate. +// specifically confirm that numTeleporterMessageBytes and TeleporterOverheadGasCost are correct. +func CalculateReceiveMessageGasLimit( + rules precompileconfig.Rules, + numSigners int, + executionRequiredGasLimit *big.Int, + numPredicateChunks int, + numTeleporterMessageBytes int, + teleporterReceiptsCount int, +) (uint64, error) { + if !executionRequiredGasLimit.IsUint64() { + return 0, errors.New("required gas limit too high") + } + + gasConfig := warp.CurrentGasConfig(rules) + + gasAmounts := []uint64{ + executionRequiredGasLimit.Uint64(), + // The variable gas on message bytes is accounted for both when used in predicate verification + // and also when used in `getVerifiedWarpMessage` + uint64(numPredicateChunks) * gasConfig.PerWarpMessageChunk * 2, + // Take into the variable gas cost for decoding the Teleporter message + // and marking the receipts as received. + uint64(numTeleporterMessageBytes) * DecodeMessageGasCostPerByte, + uint64(teleporterReceiptsCount) * MarkMessageReceiptGasCost, + uint64(numSigners) * gasConfig.PerWarpSigner, + gasConfig.VerifyPredicateBase, + gasConfig.GetVerifiedWarpMessageBase, + TeleporterOverheadGasCost, + } + + res := gasAmounts[0] + var err error + for i := 1; i < len(gasAmounts); i++ { + res, err = math.Add(res, gasAmounts[i]) + if err != nil { + return 0, err + } + } + + return res, nil +} diff --git a/icm-contracts/utils/teleporter-utils/teleporter_utils.go b/icm-contracts/utils/teleporter-utils/teleporter_utils.go new file mode 100644 index 000000000..b4692ac12 --- /dev/null +++ b/icm-contracts/utils/teleporter-utils/teleporter_utils.go @@ -0,0 +1,51 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package utils + +import ( + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/subnet-evm/accounts/abi" +) + +var ( + uint256Ty abi.Type + bytes32Ty abi.Type + addressTy abi.Type +) + +func init() { + uint256Ty, _ = abi.NewType("uint256", "uint256", nil) + bytes32Ty, _ = abi.NewType("bytes32", "bytes32", nil) + addressTy, _ = abi.NewType("address", "address", nil) +} + +func CalculateMessageID( + teleporterMessengerAddress common.Address, + sourceBlockchainID ids.ID, + destinationBlockchainID ids.ID, + nonce *big.Int, +) (ids.ID, error) { + arguments := abi.Arguments{ + {Type: addressTy}, + {Type: bytes32Ty}, + {Type: bytes32Ty}, + {Type: uint256Ty}, + } + + bytes, err := arguments.Pack( + teleporterMessengerAddress, + sourceBlockchainID, + destinationBlockchainID, + nonce, + ) + if err != nil { + return ids.ID{}, err + } + + return ids.ID(crypto.Keccak256Hash(bytes)), nil +} diff --git a/icm-contracts/utils/teleporter-utils/teleporter_utils_test.go b/icm-contracts/utils/teleporter-utils/teleporter_utils_test.go new file mode 100644 index 000000000..c18b852d5 --- /dev/null +++ b/icm-contracts/utils/teleporter-utils/teleporter_utils_test.go @@ -0,0 +1,76 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package utils + +import ( + "math/big" + "testing" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/libevm/common" + "github.com/stretchr/testify/require" +) + +var teleporterMessengerAddress = common.HexToAddress("0xfeabb3b3f4eeae6b5769507a5e6b808704e5c626") + +func TestCalculateMessageID(t *testing.T) { + testCases := []struct { + name string + teleporterMessengerAddress common.Address + sourceBlockchainID string + destinationBlockchainID string + nonce int64 + expectedID string + expectedError bool + }{ + { + name: "success1", + teleporterMessengerAddress: teleporterMessengerAddress, + sourceBlockchainID: "2D8RG4UpSXbPbvPCAWppNJyqTG2i2CAXSkTgmTBBvs7GKNZjsY", + destinationBlockchainID: "yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp", + nonce: 1, + expectedID: "ZyaPKmkZwJTJNKkUjvNLVAd5rGhcj7pUC61rtQh93Z6Ue2Fxu", + expectedError: false, + }, + { + name: "success2", + teleporterMessengerAddress: teleporterMessengerAddress, + sourceBlockchainID: "2D8RG4UpSXbPbvPCAWppNJyqTG2i2CAXSkTgmTBBvs7GKNZjsY", + destinationBlockchainID: "yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp", + nonce: 2, + expectedID: "inHeK6nYc8uhUVPygnAUPN8Wk7PGPPQXHEd9ch8vyMUPxoaA7", + expectedError: false, + }, + { + name: "success3", + teleporterMessengerAddress: teleporterMessengerAddress, + sourceBlockchainID: "2D8RG4UpSXbPbvPCAWppNJyqTG2i2CAXSkTgmTBBvs7GKNZjsY", + destinationBlockchainID: "yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp", + nonce: 3, + expectedID: "2ooMeB82Buik3jwAq3vCyb3DPuj3BAPFozALu9GsxNAw4qDdtq", + expectedError: false, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + sourceID, err := ids.FromString(test.sourceBlockchainID) + require.NoError(t, err) + destinationID, err := ids.FromString(test.destinationBlockchainID) + require.NoError(t, err) + id, err := CalculateMessageID( + test.teleporterMessengerAddress, + sourceID, + destinationID, + big.NewInt(test.nonce), + ) + if (err != nil) != test.expectedError { + t.Fatalf("expected error to be %v but got %v", test.expectedError, err) + } + if id.String() != test.expectedID { + t.Fatalf("expected id to be %v but got %v", test.expectedID, id) + } + }) + } +} diff --git a/messages/off-chain-registry/message_handler.go b/messages/off-chain-registry/message_handler.go index 3fcca653a..5de2792d9 100644 --- a/messages/off-chain-registry/message_handler.go +++ b/messages/off-chain-registry/message_handler.go @@ -11,7 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/platformvm/warp" warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" - teleporterregistry "github.com/ava-labs/icm-contracts/abi-bindings/go/teleporter/registry/TeleporterRegistry" + teleporterregistry "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/registry/TeleporterRegistry" "github.com/ava-labs/icm-services/messages" "github.com/ava-labs/icm-services/relayer/config" "github.com/ava-labs/icm-services/vms" diff --git a/messages/off-chain-registry/message_handler_test.go b/messages/off-chain-registry/message_handler_test.go index e7680fe80..414b606a4 100644 --- a/messages/off-chain-registry/message_handler_test.go +++ b/messages/off-chain-registry/message_handler_test.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" - teleporterregistry "github.com/ava-labs/icm-contracts/abi-bindings/go/teleporter/registry/TeleporterRegistry" + teleporterregistry "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/registry/TeleporterRegistry" "github.com/ava-labs/icm-services/relayer/config" mock_evm "github.com/ava-labs/icm-services/vms/evm/mocks" mock_vms "github.com/ava-labs/icm-services/vms/mocks" diff --git a/messages/teleporter/message_handler.go b/messages/teleporter/message_handler.go index 70350e146..3fc3df3e2 100644 --- a/messages/teleporter/message_handler.go +++ b/messages/teleporter/message_handler.go @@ -15,9 +15,9 @@ import ( "github.com/ava-labs/avalanchego/vms/evm/predicate" "github.com/ava-labs/avalanchego/vms/platformvm/warp" warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" - teleportermessenger "github.com/ava-labs/icm-contracts/abi-bindings/go/teleporter/TeleporterMessenger" - gasUtils "github.com/ava-labs/icm-contracts/utils/gas-utils" - teleporterUtils "github.com/ava-labs/icm-contracts/utils/teleporter-utils" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + gasUtils "github.com/ava-labs/icm-services/icm-contracts/utils/gas-utils" + teleporterUtils "github.com/ava-labs/icm-services/icm-contracts/utils/teleporter-utils" "github.com/ava-labs/icm-services/messages" pbDecider "github.com/ava-labs/icm-services/proto/pb/decider" "github.com/ava-labs/icm-services/relayer/config" diff --git a/messages/teleporter/message_handler_test.go b/messages/teleporter/message_handler_test.go index 76a32b350..7912f2b92 100644 --- a/messages/teleporter/message_handler_test.go +++ b/messages/teleporter/message_handler_test.go @@ -11,8 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/platformvm/warp" warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" - teleportermessenger "github.com/ava-labs/icm-contracts/abi-bindings/go/teleporter/TeleporterMessenger" - teleporterUtils "github.com/ava-labs/icm-contracts/utils/teleporter-utils" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + teleporterUtils "github.com/ava-labs/icm-services/icm-contracts/utils/teleporter-utils" "github.com/ava-labs/icm-services/relayer/config" mock_evm "github.com/ava-labs/icm-services/vms/evm/mocks" mock_vms "github.com/ava-labs/icm-services/vms/mocks" diff --git a/out/TeleporterMessenger.sol/combined-output.json b/out/TeleporterMessenger.sol/combined-output.json new file mode 100644 index 000000000..12b23ebe0 --- /dev/null +++ b/out/TeleporterMessenger.sol/combined-output.json @@ -0,0 +1,58480 @@ +{ + "contracts": + { + "icm-contracts/contracts/subnet-evm/IWarpMessenger.sol:IWarpMessenger": + { + "abi": + [ + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "name": "SendWarpMessage", + "type": "event" + }, + { + "inputs": [], + "name": "getBlockchainID", + "outputs": + [ + { + "internalType": "bytes32", + "name": "blockchainID", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + } + ], + "name": "getVerifiedWarpBlockHash", + "outputs": + [ + { + "components": + [ + { + "internalType": "bytes32", + "name": "sourceChainID", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "internalType": "struct WarpBlockHash", + "name": "warpBlockHash", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "valid", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint32", + "name": "index", + "type": "uint32" + } + ], + "name": "getVerifiedWarpMessage", + "outputs": + [ + { + "components": + [ + { + "internalType": "bytes32", + "name": "sourceChainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "internalType": "struct WarpMessage", + "name": "message", + "type": "tuple" + }, + { + "internalType": "bool", + "name": "valid", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes", + "name": "payload", + "type": "bytes" + } + ], + "name": "sendWarpMessage", + "outputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "", + "devdoc": + { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"SendWarpMessage\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"getBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"index\",\"type\":\"uint32\"}],\"name\":\"getVerifiedWarpBlockHash\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"sourceChainID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"struct WarpBlockHash\",\"name\":\"warpBlockHash\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"index\",\"type\":\"uint32\"}],\"name\":\"getVerifiedWarpMessage\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"sourceChainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"internalType\":\"struct WarpMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"sendWarpMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/contracts/subnet-evm/IWarpMessenger.sol\":\"IWarpMessenger\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/contracts/subnet-evm/IWarpMessenger.sol\":{\"keccak256\":\"0xda93e4a651466547d22b5574556053c188df273614549c9e2a527036b6b29652\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c4e7584e2ce261e9b8d9c2ed4c22acc9a086785c0891e8dbdad4cfba01dc14eb\",\"dweb:/ipfs/QmPZo4N5FRasJH5QLNbpDXyj4BfqhWD3fwsVjJmWu517Nk\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/contracts/teleporter/ITeleporterMessenger.sol:ITeleporterMessenger": + { + "abi": + [ + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TeleporterFeeInfo", + "name": "updatedFeeInfo", + "type": "tuple" + } + ], + "name": "AddFeeAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "blockchainID", + "type": "bytes32" + } + ], + "name": "BlockchainIDInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + } + ], + "name": "MessageExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "MessageExecutionFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + } + ], + "name": "ReceiptReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "deliverer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "rewardRedeemer", + "type": "address" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "ReceiveCrossChainMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RelayerRewardsRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + } + ], + "name": "SendCrossChainMessage", + "type": "event" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "additionalFeeAmount", + "type": "uint256" + } + ], + "name": "addFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "relayer", + "type": "address" + }, + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + } + ], + "name": "checkRelayerRewardAmount", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "getFeeInfo", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "getMessageHash", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + } + ], + "name": "getNextMessageID", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getReceiptAtIndex", + "outputs": + [ + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + } + ], + "name": "getReceiptQueueSize", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "getRelayerRewardAddress", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "messageReceived", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint32", + "name": "messageIndex", + "type": "uint32" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "name": "receiveCrossChainMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + } + ], + "name": "redeemRelayerRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "retryMessageExecution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "retrySendCrossChainMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "components": + [ + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "internalType": "struct TeleporterMessageInput", + "name": "messageInput", + "type": "tuple" + } + ], + "name": "sendCrossChainMessage", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "messageIDs", + "type": "bytes32[]" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + } + ], + "name": "sendSpecifiedReceipts", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "", + "devdoc": + { + "custom:security-contact": "https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md", + "details": "Interface that describes functionalities for a cross-chain messenger implementing the Teleporter protcol.", + "kind": "dev", + "methods": + { + "addFeeAmount(bytes32,address,uint256)": + { + "details": "The fee token address must be the same asset type as the fee asset specified in the original call to sendCrossChainMessage. Reverts if the message doesn't exist or there is already receipt of delivery of the message." + }, + "checkRelayerRewardAmount(address,address)": + { + "returns": + { + "_0": "The amount of the fee asset redeemable by the specified relayer." + } + }, + "getFeeInfo(bytes32)": + { + "returns": + { + "_0": "The fee token address and fee amount for a the given sent message ID. If the message ID is not found, zero address and amount values are returned." + } + }, + "getMessageHash(bytes32)": + { + "returns": + { + "_0": "The message hash" + } + }, + "getNextMessageID(bytes32)": + { + "details": "This message ID may never be used in the event that the next call to sendCrossChainMessage in a transaction uses a different destination blockchain. The current value as returned by this function will change with each successful call to sendCrossChainMessage.", + "returns": + { + "_0": "The specified message ID." + } + }, + "getReceiptAtIndex(bytes32,uint256)": + { + "returns": + { + "_0": "The receipt requested." + } + }, + "getReceiptQueueSize(bytes32)": + { + "returns": + { + "_0": "Size of the given queue." + } + }, + "getRelayerRewardAddress(bytes32)": + { + "returns": + { + "_0": "The relayer reward address for the given message." + } + }, + "messageReceived(bytes32)": + { + "returns": + { + "_0": "Boolean representing if the given message has been received." + } + }, + "receiveCrossChainMessage(uint32,address)": + { + "details": "The message specified by `messageIndex` must be provided at that index in the access list storage slots of the transaction, and is verified in the precompile predicate." + }, + "retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "details": "Intended to be used if message excution failed on initial delivery of the Teleporter message. For example, this may occur if the original required gas limit was not sufficient for the message execution, or if the destination address did not contain a contract, but a compatible contract was later deployed to that address. Messages are ensured to be successfully executed at most once." + }, + "retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "details": "Retriggers the sending of a message previously emitted by sendCrossChainMessage that has not yet been acknowledged with a receipt from the destination chain. This may be necessary in the unlikely event that less than the required threshold of stake weight successfully inserted the message in their messages DB at the time of the first submission. The message is checked to have already been previously submitted by comparing its message hash against those kept in state until a receipt is received for the message." + }, + "sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes))": + { + "returns": + { + "_0": "The message ID of the newly sent message." + } + }, + "sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])": + { + "details": "Sends the specified message receipts in a new message (with an empty payload) back to the source chain. This is intended for use in sending receipts that have not been sent in a timely manner by the standard receipt delivery mechanism.", + "returns": + { + "_0": "The message ID of the newly sent message." + } + } + }, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"updatedFeeInfo\",\"type\":\"tuple\"}],\"name\":\"AddFeeAmount\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"}],\"name\":\"BlockchainIDInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"MessageExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"MessageExecutionFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"ReceiptReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"deliverer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRedeemer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ReceiveCrossChainMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RelayerRewardsRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"SendCrossChainMessage\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"additionalFeeAmount\",\"type\":\"uint256\"}],\"name\":\"addFeeAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"}],\"name\":\"checkRelayerRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getFeeInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getMessageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getNextMessageID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getReceiptAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getReceiptQueueSize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getRelayerRewardAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"messageReceived\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"name\":\"receiveCrossChainMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"}],\"name\":\"redeemRelayerRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"retryMessageExecution\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"retrySendCrossChainMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"struct TeleporterMessageInput\",\"name\":\"messageInput\",\"type\":\"tuple\"}],\"name\":\"sendCrossChainMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"messageIDs\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"}],\"name\":\"sendSpecifiedReceipts\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"custom:security-contact\":\"https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md\",\"details\":\"Interface that describes functionalities for a cross-chain messenger implementing the Teleporter protcol.\",\"kind\":\"dev\",\"methods\":{\"addFeeAmount(bytes32,address,uint256)\":{\"details\":\"The fee token address must be the same asset type as the fee asset specified in the original call to sendCrossChainMessage. Reverts if the message doesn't exist or there is already receipt of delivery of the message.\"},\"checkRelayerRewardAmount(address,address)\":{\"returns\":{\"_0\":\"The amount of the fee asset redeemable by the specified relayer.\"}},\"getFeeInfo(bytes32)\":{\"returns\":{\"_0\":\"The fee token address and fee amount for a the given sent message ID. If the message ID is not found, zero address and amount values are returned.\"}},\"getMessageHash(bytes32)\":{\"returns\":{\"_0\":\"The message hash\"}},\"getNextMessageID(bytes32)\":{\"details\":\"This message ID may never be used in the event that the next call to sendCrossChainMessage in a transaction uses a different destination blockchain. The current value as returned by this function will change with each successful call to sendCrossChainMessage.\",\"returns\":{\"_0\":\"The specified message ID.\"}},\"getReceiptAtIndex(bytes32,uint256)\":{\"returns\":{\"_0\":\"The receipt requested.\"}},\"getReceiptQueueSize(bytes32)\":{\"returns\":{\"_0\":\"Size of the given queue.\"}},\"getRelayerRewardAddress(bytes32)\":{\"returns\":{\"_0\":\"The relayer reward address for the given message.\"}},\"messageReceived(bytes32)\":{\"returns\":{\"_0\":\"Boolean representing if the given message has been received.\"}},\"receiveCrossChainMessage(uint32,address)\":{\"details\":\"The message specified by `messageIndex` must be provided at that index in the access list storage slots of the transaction, and is verified in the precompile predicate.\"},\"retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"details\":\"Intended to be used if message excution failed on initial delivery of the Teleporter message. For example, this may occur if the original required gas limit was not sufficient for the message execution, or if the destination address did not contain a contract, but a compatible contract was later deployed to that address. Messages are ensured to be successfully executed at most once.\"},\"retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"details\":\"Retriggers the sending of a message previously emitted by sendCrossChainMessage that has not yet been acknowledged with a receipt from the destination chain. This may be necessary in the unlikely event that less than the required threshold of stake weight successfully inserted the message in their messages DB at the time of the first submission. The message is checked to have already been previously submitted by comparing its message hash against those kept in state until a receipt is received for the message.\"},\"sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes))\":{\"returns\":{\"_0\":\"The message ID of the newly sent message.\"}},\"sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])\":{\"details\":\"Sends the specified message receipts in a new message (with an empty payload) back to the source chain. This is intended for use in sending receipts that have not been sent in a timely manner by the standard receipt delivery mechanism.\",\"returns\":{\"_0\":\"The message ID of the newly sent message.\"}}},\"version\":1},\"userdoc\":{\"events\":{\"AddFeeAmount(bytes32,(address,uint256))\":{\"notice\":\"Emitted when an additional fee amount is added to a Teleporter message that had previously been sent, but not yet delivered to the destination chain.\"},\"BlockchainIDInitialized(bytes32)\":{\"notice\":\"Emitted when the blockchain ID of the contract instance is initialized using the Warp precompile.\"},\"MessageExecuted(bytes32,bytes32)\":{\"notice\":\"Emitted when a Teleporter message is successfully executed with the specified destination address and message call data. This can occur either when the message is initially received, or on a retry attempt. Each message received can be executed successfully at most once.\"},\"MessageExecutionFailed(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Emitted when a Teleporter message is being delivered on the destination chain to an address, but message execution fails. Failed messages can then be retried with `retryMessageExecution`\"},\"ReceiptReceived(bytes32,bytes32,address,(address,uint256))\":{\"notice\":\"Emitted when a receipt is marked as received on the source chain that sent the corresponding Teleporter message.\"},\"ReceiveCrossChainMessage(bytes32,bytes32,address,address,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Emitted when a TeleporterMessage is successfully received.\"},\"RelayerRewardsRedeemed(address,address,uint256)\":{\"notice\":\"Emitted when an account redeems accumulated relayer rewards.\"},\"SendCrossChainMessage(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes),(address,uint256))\":{\"notice\":\"Emitted when sending a Teleporter message cross-chain.\"}},\"kind\":\"user\",\"methods\":{\"addFeeAmount(bytes32,address,uint256)\":{\"notice\":\"Adds the additional fee amount to the amount to be paid to the relayer that delivers the given message ID to the destination chain.\"},\"checkRelayerRewardAmount(address,address)\":{\"notice\":\"Gets the current reward amount of a given fee asset that is redeemable by the given relayer.\"},\"getFeeInfo(bytes32)\":{\"notice\":\"Gets the fee token address and amount for a given sent message.\"},\"getMessageHash(bytes32)\":{\"notice\":\"Gets the hash of a given message stored in the EVM state, if the message exists.\"},\"getNextMessageID(bytes32)\":{\"notice\":\"Gets the message ID that would currently be used for the next message sent from the contract instance to the given destination blockchain.\"},\"getReceiptAtIndex(bytes32,uint256)\":{\"notice\":\"Gets the receipt at the given index in the queue for the given source chain ID.\"},\"getReceiptQueueSize(bytes32)\":{\"notice\":\"Gets the number of receipts that are waiting to be sent to the given source chain ID.\"},\"getRelayerRewardAddress(bytes32)\":{\"notice\":\"Returns the address the relayer reward should be sent to on the source chain for a given message, assuming that the message has already been delivered.\"},\"messageReceived(bytes32)\":{\"notice\":\"Checks whether or not the given message has been received by this chain.\"},\"receiveCrossChainMessage(uint32,address)\":{\"notice\":\"Receives a cross-chain message, and marks the `relayerRewardAddress` for fee reward for a successful delivery.\"},\"redeemRelayerRewards(address)\":{\"notice\":\"Sends any fee amount rewards for the given fee asset out to the caller.\"},\"retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Retries the execution of a previously delivered message by verifying the payload matches the hash of the payload originally delivered, and calling the destination address again.\"},\"retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Called by transactions to retry the sending of a cross-chain message.\"},\"sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes))\":{\"notice\":\"Called by transactions to initiate the sending of a cross-chain message.\"},\"sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])\":{\"notice\":\"Sends the receipts for the given `messageIDs`.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/contracts/teleporter/ITeleporterMessenger.sol\":\"ITeleporterMessenger\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/contracts/teleporter/ITeleporterMessenger.sol\":{\"keccak256\":\"0x132bfcef25900fa05c6e7319de788502d3616646577ea2d58fb303e00f1bc715\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://35a18c6f77f4efbbbb5c389e149d4eb6aa631fdaf7e8412e925dbb97efc532c7\",\"dweb:/ipfs/QmYi9mAqGSeC8SH2GJCtVqnhhhziFK5RQ21NirvGrBoton\"]}},\"version\":1}", + "userdoc": + { + "events": + { + "AddFeeAmount(bytes32,(address,uint256))": + { + "notice": "Emitted when an additional fee amount is added to a Teleporter message that had previously been sent, but not yet delivered to the destination chain." + }, + "BlockchainIDInitialized(bytes32)": + { + "notice": "Emitted when the blockchain ID of the contract instance is initialized using the Warp precompile." + }, + "MessageExecuted(bytes32,bytes32)": + { + "notice": "Emitted when a Teleporter message is successfully executed with the specified destination address and message call data. This can occur either when the message is initially received, or on a retry attempt. Each message received can be executed successfully at most once." + }, + "MessageExecutionFailed(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Emitted when a Teleporter message is being delivered on the destination chain to an address, but message execution fails. Failed messages can then be retried with `retryMessageExecution`" + }, + "ReceiptReceived(bytes32,bytes32,address,(address,uint256))": + { + "notice": "Emitted when a receipt is marked as received on the source chain that sent the corresponding Teleporter message." + }, + "ReceiveCrossChainMessage(bytes32,bytes32,address,address,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Emitted when a TeleporterMessage is successfully received." + }, + "RelayerRewardsRedeemed(address,address,uint256)": + { + "notice": "Emitted when an account redeems accumulated relayer rewards." + }, + "SendCrossChainMessage(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes),(address,uint256))": + { + "notice": "Emitted when sending a Teleporter message cross-chain." + } + }, + "kind": "user", + "methods": + { + "addFeeAmount(bytes32,address,uint256)": + { + "notice": "Adds the additional fee amount to the amount to be paid to the relayer that delivers the given message ID to the destination chain." + }, + "checkRelayerRewardAmount(address,address)": + { + "notice": "Gets the current reward amount of a given fee asset that is redeemable by the given relayer." + }, + "getFeeInfo(bytes32)": + { + "notice": "Gets the fee token address and amount for a given sent message." + }, + "getMessageHash(bytes32)": + { + "notice": "Gets the hash of a given message stored in the EVM state, if the message exists." + }, + "getNextMessageID(bytes32)": + { + "notice": "Gets the message ID that would currently be used for the next message sent from the contract instance to the given destination blockchain." + }, + "getReceiptAtIndex(bytes32,uint256)": + { + "notice": "Gets the receipt at the given index in the queue for the given source chain ID." + }, + "getReceiptQueueSize(bytes32)": + { + "notice": "Gets the number of receipts that are waiting to be sent to the given source chain ID." + }, + "getRelayerRewardAddress(bytes32)": + { + "notice": "Returns the address the relayer reward should be sent to on the source chain for a given message, assuming that the message has already been delivered." + }, + "messageReceived(bytes32)": + { + "notice": "Checks whether or not the given message has been received by this chain." + }, + "receiveCrossChainMessage(uint32,address)": + { + "notice": "Receives a cross-chain message, and marks the `relayerRewardAddress` for fee reward for a successful delivery." + }, + "redeemRelayerRewards(address)": + { + "notice": "Sends any fee amount rewards for the given fee asset out to the caller." + }, + "retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Retries the execution of a previously delivered message by verifying the payload matches the hash of the payload originally delivered, and calling the destination address again." + }, + "retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Called by transactions to retry the sending of a cross-chain message." + }, + "sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes))": + { + "notice": "Called by transactions to initiate the sending of a cross-chain message." + }, + "sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])": + { + "notice": "Sends the receipts for the given `messageIDs`." + } + }, + "version": 1 + } + }, + "icm-contracts/contracts/teleporter/ITeleporterReceiver.sol:ITeleporterReceiver": + { + "abi": + [ + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "name": "receiveTeleporterMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "", + "devdoc": + { + "custom:security-contact": "https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md", + "details": "Interface that cross-chain applications must implement to receive messages from Teleporter.", + "kind": "dev", + "methods": + { + "receiveTeleporterMessage(bytes32,address,bytes)": + { + "details": "Called by TeleporterMessenger on the receiving chain.", + "params": + { + "message": "is the TeleporterMessage payload set by the sender.", + "originSenderAddress": "is provided by the TeleporterMessenger contract.", + "sourceBlockchainID": "is provided by the TeleporterMessenger contract." + } + } + }, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"custom:security-contact\":\"https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md\",\"details\":\"Interface that cross-chain applications must implement to receive messages from Teleporter.\",\"kind\":\"dev\",\"methods\":{\"receiveTeleporterMessage(bytes32,address,bytes)\":{\"details\":\"Called by TeleporterMessenger on the receiving chain.\",\"params\":{\"message\":\"is the TeleporterMessage payload set by the sender.\",\"originSenderAddress\":\"is provided by the TeleporterMessenger contract.\",\"sourceBlockchainID\":\"is provided by the TeleporterMessenger contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/contracts/teleporter/ITeleporterReceiver.sol\":\"ITeleporterReceiver\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/contracts/teleporter/ITeleporterReceiver.sol\":{\"keccak256\":\"0x3a3cd5b52193d940d634d4754f51f423e75c927a86d3eb91d5a583eb54ef9cd6\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://96843ce304eaedceea3b2b5aca57be97fc200e58533045c544ad7bba62223e86\",\"dweb:/ipfs/QmYMvWLqpRqENKrKwhLTcWrQbqtdo35zLJpgMxzKE2ZznV\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/contracts/teleporter/ReceiptQueue.sol:ReceiptQueue": + { + "abi": [], + "bin": "60556032600b8282823980515f1a607314602657634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220265dc33bea2e321f921aa4baf87e1cefaa331f0e8c5fcf42c9224b679a96b65b64736f6c63430008190033", + "devdoc": + { + "custom:security-contact": "https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md", + "details": "ReceiptQueue is a convenience library that creates a queue-like interface of TeleporterMessageReceipt structs. It provides FIFO properties. Note: All functions in this library are internal so that the library is not deployed as a contract.", + "kind": "dev", + "methods": {}, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"custom:security-contact\":\"https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md\",\"details\":\"ReceiptQueue is a convenience library that creates a queue-like interface of TeleporterMessageReceipt structs. It provides FIFO properties. Note: All functions in this library are internal so that the library is not deployed as a contract.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/contracts/teleporter/ReceiptQueue.sol\":\"ReceiptQueue\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/contracts/teleporter/ITeleporterMessenger.sol\":{\"keccak256\":\"0x132bfcef25900fa05c6e7319de788502d3616646577ea2d58fb303e00f1bc715\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://35a18c6f77f4efbbbb5c389e149d4eb6aa631fdaf7e8412e925dbb97efc532c7\",\"dweb:/ipfs/QmYi9mAqGSeC8SH2GJCtVqnhhhziFK5RQ21NirvGrBoton\"]},\"icm-contracts/contracts/teleporter/ReceiptQueue.sol\":{\"keccak256\":\"0x79bbf8faa818cc8834034e7ae37e38f53fdff71540277e73c06a68dfa9c2e45e\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://076fbb8461c4758f6b5c3e8a91607292cdf95a1b7fb030448c288932746a1434\",\"dweb:/ipfs/QmcjxZZW4HnAbcWB1EHsT6Tw7V5ChJ4YQu8Lb7b7VzoRhp\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ece9f0b9c8daca08c76b6b5405a6446b6f73b3a15fab7ff56e296cbd4a2c875\",\"dweb:/ipfs/QmQyRpyPRL5SQuAgj6SHmbir3foX65FJjbVTTQrA2EFg6L\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/contracts/teleporter/TeleporterMessenger.sol:TeleporterMessenger": + { + "abi": + [ + { + "inputs": + [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TeleporterFeeInfo", + "name": "updatedFeeInfo", + "type": "tuple" + } + ], + "name": "AddFeeAmount", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "blockchainID", + "type": "bytes32" + } + ], + "name": "BlockchainIDInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + } + ], + "name": "MessageExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "MessageExecutionFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + } + ], + "name": "ReceiptReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "deliverer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "rewardRedeemer", + "type": "address" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "ReceiveCrossChainMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RelayerRewardsRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + } + ], + "name": "SendCrossChainMessage", + "type": "event" + }, + { + "inputs": [], + "name": "WARP_MESSENGER", + "outputs": + [ + { + "internalType": "contract IWarpMessenger", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "additionalFeeAmount", + "type": "uint256" + } + ], + "name": "addFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "blockchainID", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "name": "calculateMessageID", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "relayer", + "type": "address" + }, + { + "internalType": "address", + "name": "feeAsset", + "type": "address" + } + ], + "name": "checkRelayerRewardAmount", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "getFeeInfo", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "getMessageHash", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + } + ], + "name": "getNextMessageID", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getReceiptAtIndex", + "outputs": + [ + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + } + ], + "name": "getReceiptQueueSize", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "getRelayerRewardAddress", + "outputs": + [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initializeBlockchainID", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "messageNonce", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "messageReceived", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + } + ], + "name": "receiptQueues", + "outputs": + [ + { + "internalType": "uint256", + "name": "first", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "last", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "uint32", + "name": "messageIndex", + "type": "uint32" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "name": "receiveCrossChainMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "receivedFailedMessageHashes", + "outputs": + [ + { + "internalType": "bytes32", + "name": "messageHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "feeAsset", + "type": "address" + } + ], + "name": "redeemRelayerRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "retryMessageExecution", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "components": + [ + { + "internalType": "uint256", + "name": "messageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "originSenderAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "components": + [ + { + "internalType": "uint256", + "name": "receivedMessageNonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "relayerRewardAddress", + "type": "address" + } + ], + "internalType": "struct TeleporterMessageReceipt[]", + "name": "receipts", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "internalType": "struct TeleporterMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "retrySendCrossChainMessage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "components": + [ + { + "internalType": "bytes32", + "name": "destinationBlockchainID", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "destinationAddress", + "type": "address" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "requiredGasLimit", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + } + ], + "internalType": "struct TeleporterMessageInput", + "name": "messageInput", + "type": "tuple" + } + ], + "name": "sendCrossChainMessage", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "sourceBlockchainID", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "messageIDs", + "type": "bytes32[]" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + }, + { + "internalType": "address[]", + "name": "allowedRelayerAddresses", + "type": "address[]" + } + ], + "name": "sendSpecifiedReceipts", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "bytes32", + "name": "messageID", + "type": "bytes32" + } + ], + "name": "sentMessageInfo", + "outputs": + [ + { + "internalType": "bytes32", + "name": "messageHash", + "type": "bytes32" + }, + { + "components": + [ + { + "internalType": "address", + "name": "feeTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct TeleporterFeeInfo", + "name": "feeInfo", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bin": "6080604052348015600e575f80fd5b5060015f8190558055613142806100245f395ff3fe608060405234801561000f575f80fd5b5060043610610148575f3560e01c8063a8898181116100bf578063df20e8bc11610079578063df20e8bc14610331578063e69d606a14610344578063e6e67bd5146103ab578063ebc3b1ba146103e6578063ecc7042814610409578063fc2d619714610412575f80fd5b8063a8898181146102a9578063a9a85614146102bc578063b771b3bc146102cf578063c473eef8146102dd578063ccb5f80914610315578063d127dc9b14610328575f80fd5b8063399b77da11610110578063399b77da1461021257806362448850146102315780638245a1b014610244578063860a3b0614610257578063892bf412146102765780638ac0fd0414610296575f80fd5b80630af5b4ff1461014c57806322296c3a146101675780632bc8b0bf1461017c5780632ca40f551461018f5780632e27c223146101e7575b5f80fd5b610154610425565b6040519081526020015b60405180910390f35b61017a610175366004612138565b6104f3565b005b61015461018a366004612153565b6105e6565b6101d961019d366004612153565b600560209081525f9182526040918290208054835180850190945260018201546001600160a01b03168452600290910154918301919091529082565b60405161015e92919061216a565b6101fa6101f5366004612153565b610602565b6040516001600160a01b03909116815260200161015e565b610154610220366004612153565b5f9081526005602052604090205490565b61015461023f366004612191565b610689565b61017a6102523660046121de565b6106e2565b610154610265366004612153565b60066020525f908152604090205481565b61028961028436600461220f565b610885565b60405161015e919061222f565b61017a6102a436600461224f565b6108b6565b6101546102b7366004612284565b610aed565b6101546102ca3660046122f4565b610b2f565b6101fa6005600160991b0181565b6101546102eb366004612385565b6001600160a01b039182165f90815260096020908152604080832093909416825291909152205490565b61017a6103233660046123bc565b610dc1565b61015460025481565b61015461033f366004612153565b6111e3565b61038c610352366004612153565b5f90815260056020908152604091829020825180840190935260018101546001600160a01b03168084526002909101549290910182905291565b604080516001600160a01b03909316835260208301919091520161015e565b6103d16103b9366004612153565b60046020525f90815260409020805460019091015482565b6040805192835260208301919091520161015e565b6103f96103f4366004612153565b61122a565b604051901515815260200161015e565b61015460035481565b61017a6104203660046123e0565b61123f565b6002545f90806104ee576005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104969190612423565b9050806104be5760405162461bcd60e51b81526004016104b59061243a565b60405180910390fd5b600281905560405181907f1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104905f90a25b919050565b335f9081526009602090815260408083206001600160a01b0385168452909152902054806105745760405162461bcd60e51b815260206004820152602860248201527f54656c65706f727465724d657373656e6765723a206e6f2072657761726420746044820152676f2072656465656d60c01b60648201526084016104b5565b335f8181526009602090815260408083206001600160a01b03871680855290835281842093909355518481529192917f3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88910160405180910390a36105e26001600160a01b0383163383611494565b5050565b5f8181526004602052604081206105fc906114f8565b92915050565b5f8181526007602052604081205461066e5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f74604482015268081c9958d95a5d995960ba1b60648201526084016104b5565b505f908152600860205260409020546001600160a01b031690565b5f60015f54146106ab5760405162461bcd60e51b81526004016104b590612481565b60025f556106d86106bb836126b8565b83355f9081526004602052604090206106d39061150a565b611604565b60015f5592915050565b60015f54146107035760405162461bcd60e51b81526004016104b590612481565b60025f818155905461071b9060408401358435610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b0316845260029091015483830152908101919091528051919250906107825760405162461bcd60e51b81526004016104b590612757565b5f8360405160200161079491906129d6565b60408051601f19818403018152919052825181516020830120919250146107cd5760405162461bcd60e51b81526004016104b5906129e8565b8360400135837f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8868560200151604051610808929190612a31565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb9061083a908490600401612ab2565b6020604051808303815f875af1158015610856573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061087a9190612423565b505060015f55505050565b604080518082019091525f80825260208201525f8381526004602052604090206108af9083611837565b9392505050565b60015f54146108d75760405162461bcd60e51b81526004016104b590612481565b60025f5560018054146108fc5760405162461bcd60e51b81526004016104b590612ac4565b6002600155806109665760405162461bcd60e51b815260206004820152602f60248201527f54656c65706f727465724d657373656e6765723a207a65726f2061646469746960448201526e1bdb985b0819995948185b5bdd5b9d608a1b60648201526084016104b5565b6001600160a01b03821661098c5760405162461bcd60e51b81526004016104b590612b09565b5f838152600560205260409020546109b65760405162461bcd60e51b81526004016104b590612757565b5f838152600560205260409020600101546001600160a01b03838116911614610a475760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642066656560448201527f20617373657420636f6e7472616374206164647265737300000000000000000060648201526084016104b5565b5f610a5283836118f8565b5f85815260056020526040812060020180549293508392909190610a77908490612b71565b90915550505f8481526005602052604090819020905185917fc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e191610ad8916001019081546001600160a01b0316815260019190910154602082015260400190565b60405180910390a2505060018080555f555050565b6040805130602082015290810184905260608101839052608081018290525f9060a0016040516020818303038152906040528051906020012090509392505050565b5f60015f5414610b515760405162461bcd60e51b81526004016104b590612481565b60025f818155905490866001600160401b03811115610b7257610b726124c4565b604051908082528060200260200182016040528015610bb657816020015b604080518082019091525f8082526020820152815260200190600190039081610b905790505b509050865f5b81811015610d2e575f8a8a83818110610bd757610bd7612b84565b9050602002013590505f60075f8381526020019081526020015f20549050805f03610c535760405162461bcd60e51b815260206004820152602660248201527f54656c65706f727465724d657373656e6765723a2072656365697074206e6f7460448201526508199bdd5b9960d21b60648201526084016104b5565b610c5e8d8783610aed565b8214610cd25760405162461bcd60e51b815260206004820152603a60248201527f54656c65706f727465724d657373656e6765723a206d6573736167652049442060448201527f6e6f742066726f6d20736f7572636520626c6f636b636861696e00000000000060648201526084016104b5565b5f828152600860209081526040918290205482518084019093528383526001600160a01b03169082018190528651909190879086908110610d1557610d15612b84565b6020026020010181905250505050806001019050610bbc565b506040805160c0810182528b81525f6020820152610daf918101610d57368b90038b018b612b98565b81526020015f81526020018888808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052509385525050604080519283526020808401909152909201525083611604565b60015f559a9950505050505050505050565b6001805414610de25760405162461bcd60e51b81526004016104b590612ac4565b60026001556040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610e30573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e579190810190612c0e565b9150915080610eba5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642077617260448201526870206d65737361676560b81b60648201526084016104b5565b60208201516001600160a01b03163014610f315760405162461bcd60e51b815260206004820152603260248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206f726960448201527167696e2073656e646572206164647265737360701b60648201526084016104b5565b5f8260400151806020019051810190610f4a9190612da2565b90505f610f55610425565b905080826040015114610fc45760405162461bcd60e51b815260206004820152603160248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206465736044820152701d1a5b985d1a5bdb8818da185a5b881251607a1b60648201526084016104b5565b835182515f91610fd5918490610aed565b5f81815260076020526040902054909150156110495760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f727465724d657373656e6765723a206d65737361676520616c7260448201526c1958591e481c9958d95a5d9959609a1b60648201526084016104b5565b611057338460a00151611904565b6110b55760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20756e617574686f72697a6560448201526832103932b630bcb2b960b91b60648201526084016104b5565b6110c281845f0151611970565b6001600160a01b038616156110f8575f81815260086020526040902080546001600160a01b0319166001600160a01b0388161790555b60c0830151515f5b8181101561113b5761113384885f01518760c00151848151811061112657611126612b84565b60200260200101516119e0565b600101611100565b50604080518082018252855181526001600160a01b03891660208083019190915288515f90815260049091529190912061117491611b04565b336001600160a01b0316865f0151837f292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e348a886040516111b4929190612fb1565b60405180910390a460e084015151156111d5576111d582875f015186611b5e565b505060018055505050505050565b6002545f90806112055760405162461bcd60e51b81526004016104b59061243a565b5f60035460016112159190612b71565b9050611222828583610aed565b949350505050565b5f8181526007602052604081205415156105fc565b60018054146112605760405162461bcd60e51b81526004016104b590612ac4565b60026001819055545f906112779084908435610aed565b5f81815260066020526040902054909150806112a55760405162461bcd60e51b81526004016104b590612757565b80836040516020016112b791906129d6565b60405160208183030381529060405280519060200120146112ea5760405162461bcd60e51b81526004016104b5906129e8565b5f6112fb6080850160608601612138565b6001600160a01b03163b1161136f5760405162461bcd60e51b815260206004820152603460248201527f54656c65706f727465724d657373656e6765723a2064657374696e6174696f6e604482015273206164647265737320686173206e6f20636f646560601b60648201526084016104b5565b604051849083907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35f82815260066020908152604080832083905586916113be918701908701612138565b6113cb60e0870187612fd4565b6040516024016113de9493929190613016565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b17905290505f61142561141e6080870160608801612138565b5a84611c8d565b9050806114885760405162461bcd60e51b815260206004820152602b60248201527f54656c65706f727465724d657373656e6765723a20726574727920657865637560448201526a1d1a5bdb8819985a5b195960aa1b60648201526084016104b5565b50506001805550505050565b6040516001600160a01b038381166024830152604482018390526114f391859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ca4565b505050565b805460018201545f916105fc91613040565b60605f611520600561151b856114f8565b611d05565b9050805f0361156c57604080515f8082526020820190925290611564565b604080518082019091525f808252602082015281526020019060019003908161153e5790505b509392505050565b5f816001600160401b03811115611585576115856124c4565b6040519080825280602002602001820160405280156115c957816020015b604080518082019091525f80825260208201528152602001906001900390816115a35790505b5090505f5b82811015611564576115df85611d1a565b8282815181106115f1576115f1612b84565b60209081029190910101526001016115ce565b5f8061160e610425565b90505f60035f815461161f90613053565b91905081905590505f61163683875f015184610aed565b90505f604051806101000160405280848152602001336001600160a01b03168152602001885f0151815260200188602001516001600160a01b0316815260200188606001518152602001886080015181526020018781526020018860a0015181525090505f816040516020016116ac919061306b565b60405160208183030381529060405290505f808960400151602001511115611713576040890151516001600160a01b03166116f95760405162461bcd60e51b81526004016104b590612b09565b6040890151805160209091015161171091906118f8565b90505b6040805180820182528a820151516001600160a01b03908116825260208083018590528351808501855286518783012081528082018481525f8a815260058452869020915182555180516001830180546001600160a01b03191691909516179093559101516002909101558a51915190919086907f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8906117b6908890869061307d565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb906117e8908690600401612ab2565b6020604051808303815f875af1158015611804573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118289190612423565b50939998505050505050505050565b604080518082019091525f8082526020820152611853836114f8565b82106118ab5760405162461bcd60e51b815260206004820152602160248201527f5265636569707451756575653a20696e646578206f7574206f6620626f756e646044820152607360f81b60648201526084016104b5565b826002015f83855f01546118bf9190612b71565b815260208082019290925260409081015f20815180830190925280548252600101546001600160a01b0316918101919091529392505050565b5f6108af833384611de4565b5f81515f03611915575060016105fc565b81515f5b8181101561196657846001600160a01b031684828151811061193d5761193d612b84565b60200260200101516001600160a01b03160361195e576001925050506105fc565b600101611919565b505f949350505050565b805f036119cf5760405162461bcd60e51b815260206004820152602760248201527f54656c65706f727465724d657373656e6765723a207a65726f206d657373616760448201526665206e6f6e636560c81b60648201526084016104b5565b5f9182526007602052604090912055565b5f6119ef8484845f0151610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b031684526002909101548383015290810191909152805191925090611a45575050505050565b5f8281526005602090815260408083208381556001810180546001600160a01b03191690556002018390558382018051830151878401516001600160a01b0390811686526009855283862092515116855292528220805491929091611aab908490612b71565b9250508190555082602001516001600160a01b031684837fd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf578460200151604051611af5919061308f565b60405180910390a45050505050565b600182018054829160028501915f9182611b1d83613053565b9091555081526020808201929092526040015f2082518155910151600190910180546001600160a01b0319166001600160a01b039092169190911790555050565b80608001515a1015611bc05760405162461bcd60e51b815260206004820152602560248201527f54656c65706f727465724d657373656e6765723a20696e73756666696369656e604482015264742067617360d81b60648201526084016104b5565b80606001516001600160a01b03163b5f03611be0576114f3838383611f47565b602081015160e08201516040515f92611bfd9286926024016130af565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b179052606083015160808401519192505f91611c41919084611c8d565b905080611c5a57611c53858585611f47565b5050505050565b604051849086907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35050505050565b5f805f808451602086015f8989f195945050505050565b5f611cb86001600160a01b03841683611fbb565b905080515f14158015611cdc575080806020019051810190611cda91906130d8565b155b156114f357604051635274afe760e01b81526001600160a01b03841660048201526024016104b5565b5f818310611d1357816108af565b5090919050565b604080518082019091525f808252602082015281546001830154819003611d835760405162461bcd60e51b815260206004820152601960248201527f5265636569707451756575653a20656d7074792071756575650000000000000060448201526064016104b5565b5f8181526002840160208181526040808420815180830190925280548252600180820180546001600160a01b03811685870152888852959094529490556001600160a01b0319909216905590611dda908390612b71565b9093555090919050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038616906370a0823190602401602060405180830381865afa158015611e2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e4e9190612423565b9050611e656001600160a01b038616853086611fc8565b6040516370a0823160e01b81523060048201525f906001600160a01b038716906370a0823190602401602060405180830381865afa158015611ea9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ecd9190612423565b9050818111611f335760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016104b5565b611f3d8282613040565b9695505050505050565b80604051602001611f58919061306b565b60408051601f1981840301815282825280516020918201205f878152600690925291902055829084907f4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c98590611fae90859061306b565b60405180910390a3505050565b60606108af83835f612007565b6040516001600160a01b0384811660248301528381166044830152606482018390526120019186918216906323b872dd906084016114c1565b50505050565b60608147101561202c5760405163cd78605960e01b81523060048201526024016104b5565b5f80856001600160a01b0316848660405161204791906130f1565b5f6040518083038185875af1925050503d805f8114612081576040519150601f19603f3d011682016040523d82523d5f602084013e612086565b606091505b5091509150611f3d8683836060826120a6576120a1826120ed565b6108af565b81511580156120bd57506001600160a01b0384163b155b156120e657604051639996b31560e01b81526001600160a01b03851660048201526024016104b5565b50806108af565b8051156120fd5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6001600160a01b0381168114612116575f80fd5b80356104ee81612119565b5f60208284031215612148575f80fd5b81356108af81612119565b5f60208284031215612163575f80fd5b5035919050565b828152606081016108af602083018480516001600160a01b03168252602090810151910152565b5f602082840312156121a1575f80fd5b81356001600160401b038111156121b6575f80fd5b820160e081850312156108af575f80fd5b5f61010082840312156121d8575f80fd5b50919050565b5f602082840312156121ee575f80fd5b81356001600160401b03811115612203575f80fd5b611222848285016121c7565b5f8060408385031215612220575f80fd5b50508035926020909101359150565b815181526020808301516001600160a01b031690820152604081016105fc565b5f805f60608486031215612261575f80fd5b83359250602084013561227381612119565b929592945050506040919091013590565b5f805f60608486031215612296575f80fd5b505081359360208301359350604090920135919050565b5f8083601f8401126122bd575f80fd5b5081356001600160401b038111156122d3575f80fd5b6020830191508360208260051b85010111156122ed575f80fd5b9250929050565b5f805f805f8086880360a081121561230a575f80fd5b8735965060208801356001600160401b0380821115612327575f80fd5b6123338b838c016122ad565b90985096508691506040603f198401121561234c575f80fd5b60408a01955060808a0135925080831115612365575f80fd5b505061237389828a016122ad565b979a9699509497509295939492505050565b5f8060408385031215612396575f80fd5b82356123a181612119565b915060208301356123b181612119565b809150509250929050565b5f80604083850312156123cd575f80fd5b823563ffffffff811681146123a1575f80fd5b5f80604083850312156123f1575f80fd5b8235915060208301356001600160401b0381111561240d575f80fd5b612419858286016121c7565b9150509250929050565b5f60208284031215612433575f80fd5b5051919050565b60208082526027908201527f54656c65706f727465724d657373656e6765723a207a65726f20626c6f636b636040820152661a185a5b88125160ca1b606082015260800190565b60208082526023908201527f5265656e7472616e63794775617264733a2073656e646572207265656e7472616040820152626e637960e81b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156124fa576124fa6124c4565b60405290565b60405160c081016001600160401b03811182821017156124fa576124fa6124c4565b60405161010081016001600160401b03811182821017156124fa576124fa6124c4565b604051601f8201601f191681016001600160401b038111828210171561256d5761256d6124c4565b604052919050565b5f60408284031215612585575f80fd5b61258d6124d8565b9050813561259a81612119565b808252506020820135602082015292915050565b5f6001600160401b038211156125c6576125c66124c4565b5060051b60200190565b5f82601f8301126125df575f80fd5b813560206125f46125ef836125ae565b612545565b8083825260208201915060208460051b870101935086841115612615575f80fd5b602086015b8481101561263a57803561262d81612119565b835291830191830161261a565b509695505050505050565b5f6001600160401b0382111561265d5761265d6124c4565b50601f01601f191660200190565b5f82601f83011261267a575f80fd5b81356126886125ef82612645565b81815284602083860101111561269c575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60e082360312156126c8575f80fd5b6126d0612500565b823581526126e06020840161212d565b60208201526126f23660408501612575565b60408201526080830135606082015260a08301356001600160401b038082111561271a575f80fd5b612726368387016125d0565b608084015260c085013591508082111561273e575f80fd5b5061274b3682860161266b565b60a08301525092915050565b60208082526026908201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f7460408201526508199bdd5b9960d21b606082015260800190565b5f808335601e198436030181126127b2575f80fd5b83016020810192503590506001600160401b038111156127d0575f80fd5b8060051b36038213156122ed575f80fd5b8183525f60208085019450825f5b8581101561281d57813561280281612119565b6001600160a01b0316875295820195908201906001016127ef565b509495945050505050565b5f808335601e1984360301811261283d575f80fd5b83016020810192503590506001600160401b0381111561285b575f80fd5b8060061b36038213156122ed575f80fd5b8183525f60208085019450825f5b8581101561281d57813587528282013561289381612119565b6001600160a01b031687840152604096870196919091019060010161287a565b5f808335601e198436030181126128c8575f80fd5b83016020810192503590506001600160401b038111156128e6575f80fd5b8036038213156122ed575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f61010082358452602083013561293281612119565b6001600160a01b03166020850152604083810135908501526129566060840161212d565b6001600160a01b031660608501526080838101359085015261297b60a084018461279d565b8260a087015261298e83870182846127e1565b9250505061299f60c0840184612828565b85830360c08701526129b283828461286c565b925050506129c360e08401846128b3565b85830360e0870152611f3d8382846128f4565b602081525f6108af602083018461291c565b60208082526029908201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206d65736040820152680e6c2ceca40d0c2e6d60bb1b606082015260800190565b606081525f612a43606083018561291c565b90506108af602083018480516001600160a01b03168252602090810151910152565b5f5b83811015612a7f578181015183820152602001612a67565b50505f910152565b5f8151808452612a9e816020860160208601612a65565b601f01601f19169290920160200192915050565b602081525f6108af6020830184612a87565b60208082526025908201527f5265656e7472616e63794775617264733a207265636569766572207265656e7460408201526472616e637960d81b606082015260800190565b60208082526034908201527f54656c65706f727465724d657373656e6765723a207a65726f2066656520617360408201527373657420636f6e7472616374206164647265737360601b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105fc576105fc612b5d565b634e487b7160e01b5f52603260045260245ffd5b5f60408284031215612ba8575f80fd5b6108af8383612575565b80516104ee81612119565b5f82601f830112612bcc575f80fd5b8151612bda6125ef82612645565b818152846020838601011115612bee575f80fd5b611222826020830160208701612a65565b805180151581146104ee575f80fd5b5f8060408385031215612c1f575f80fd5b82516001600160401b0380821115612c35575f80fd5b9084019060608287031215612c48575f80fd5b604051606081018181108382111715612c6357612c636124c4565b604052825181526020830151612c7881612119565b6020820152604083015182811115612c8e575f80fd5b612c9a88828601612bbd565b6040830152509350612cb191505060208401612bff565b90509250929050565b5f82601f830112612cc9575f80fd5b81516020612cd96125ef836125ae565b8083825260208201915060208460051b870101935086841115612cfa575f80fd5b602086015b8481101561263a578051612d1281612119565b8352918301918301612cff565b5f82601f830112612d2e575f80fd5b81516020612d3e6125ef836125ae565b82815260069290921b84018101918181019086841115612d5c575f80fd5b8286015b8481101561263a5760408189031215612d77575f80fd5b612d7f6124d8565b8151815284820151612d9081612119565b81860152835291830191604001612d60565b5f60208284031215612db2575f80fd5b81516001600160401b0380821115612dc8575f80fd5b908301906101008286031215612ddc575f80fd5b612de4612522565b82518152612df460208401612bb2565b602082015260408301516040820152612e0f60608401612bb2565b60608201526080830151608082015260a083015182811115612e2f575f80fd5b612e3b87828601612cba565b60a08301525060c083015182811115612e52575f80fd5b612e5e87828601612d1f565b60c08301525060e083015182811115612e75575f80fd5b612e8187828601612bbd565b60e08301525095945050505050565b5f815180845260208085019450602084015f5b8381101561281d5781516001600160a01b031687529582019590820190600101612ea3565b5f815180845260208085019450602084015f5b8381101561281d57612f01878351805182526020908101516001600160a01b0316910152565b6040969096019590820190600101612edb565b5f6101008251845260018060a01b036020840151166020850152604083015160408501526060830151612f5260608601826001600160a01b03169052565b506080830151608085015260a08301518160a0860152612f7482860182612e90565b91505060c083015184820360c0860152612f8e8282612ec8565b91505060e083015184820360e0860152612fa88282612a87565b95945050505050565b6001600160a01b03831681526040602082018190525f9061122290830184612f14565b5f808335601e19843603018112612fe9575f80fd5b8301803591506001600160401b03821115613002575f80fd5b6020019150368190038213156122ed575f80fd5b8481526001600160a01b03841660208201526060604082018190525f90611f3d90830184866128f4565b818103818111156105fc576105fc612b5d565b5f6001820161306457613064612b5d565b5060010190565b602081525f6108af6020830184612f14565b606081525f612a436060830185612f14565b81516001600160a01b0316815260208083015190820152604081016105fc565b8381526001600160a01b03831660208201526060604082018190525f90612fa890830184612a87565b5f602082840312156130e8575f80fd5b6108af82612bff565b5f8251613102818460208701612a65565b919091019291505056fea2646970667358221220b9da062aeff8ff40d9d6ae3926de95e3f58630dfbe8975613e70ec0e8afd6b0764736f6c63430008190033", + "devdoc": + { + "custom:security-contact": "https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md", + "details": "Implementation of the {ITeleporterMessenger} interface. This implementation is used to send messages cross chain using the IWarpMessenger precompile, and to receive messages sent from other chains. Teleporter contracts should be deployed through Nick's method of universal deployer, such that the same contract is deployed at the same address on all chains.", + "errors": + { + "AddressEmptyCode(address)": + [ + { + "details": "There's no code at `target` (it is not a contract)." + } + ], + "AddressInsufficientBalance(address)": + [ + { + "details": "The ETH balance of the account is not enough to perform the operation." + } + ], + "FailedInnerCall()": + [ + { + "details": "A call to an address target failed. The target may have reverted." + } + ], + "SafeERC20FailedOperation(address)": + [ + { + "details": "An operation with an ERC20 token failed." + } + ] + }, + "kind": "dev", + "methods": + { + "addFeeAmount(bytes32,address,uint256)": + { + "details": "Both `senderNonReentrant` and `receiverNonReentrant` are used here to prevent the external call of `safeTransferFrom` from being reentrant, calling `receiveCrossChainMessage` to attribute rewards for this message, and then still adding fee amount for this message. Emits an {AddFeeAmount} event. Requirements: - `additionalFeeAmount` must be non-zero. - `message` must exist and not have been acknowledged with a receipt yet. - `feeTokenAddress` must match the fee asset contract address used in the original call to `sendCrossChainMessage`." + }, + "checkRelayerRewardAmount(address,address)": + { + "returns": + { + "_0": "The amount of the fee asset redeemable by the specified relayer." + } + }, + "getFeeInfo(bytes32)": + { + "returns": + { + "_0": "The fee token address and fee amount for a the given sent message ID. If the message ID is not found, zero address and amount values are returned." + } + }, + "getMessageHash(bytes32)": + { + "returns": + { + "_0": "The message hash" + } + }, + "getNextMessageID(bytes32)": + { + "returns": + { + "_0": "The next message ID to be used for a message sent from the contract instance." + } + }, + "getReceiptAtIndex(bytes32,uint256)": + { + "returns": + { + "_0": "The receipt requested." + } + }, + "getReceiptQueueSize(bytes32)": + { + "returns": + { + "_0": "Size of the given queue." + } + }, + "getRelayerRewardAddress(bytes32)": + { + "returns": + { + "_0": "The relayer reward address for the given message." + } + }, + "initializeBlockchainID()": + { + "details": "Emits {BlockchainIDInitialized} event.", + "returns": + { + "_0": "The current blockchain ID." + } + }, + "messageReceived(bytes32)": + { + "returns": + { + "_0": "Boolean representing if the given message has been received." + } + }, + "receiveCrossChainMessage(uint32,address)": + { + "details": "Emits a {ReceiveCrossChainMessage} event. Re-entrancy is explicitly disallowed between receiving functions. One message is not able to receive another message. Requirements: - `relayerRewardAddress` must not be the zero address. - `messageIndex` must specify a valid warp message in the transaction's storage slots. - Valid warp message provided in storage slots, and sender address matches the address of this contract. - Teleporter message `destinationBlockchainID` must match the `blockchainID` of this contract. - Teleporter message was not previously received. - Transaction was sent by an allowed relayer for corresponding teleporter message." + }, + "redeemRelayerRewards(address)": + { + "details": "Requirements: - `rewardAmount` must be non-zero." + }, + "retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "details": "A Teleporter message has an associated `requiredGasLimit` that is used to execute the message. If the `requiredGasLimit` is too low, then the message execution will fail. This method allows for retrying the execution of a message with a higher gas limit. Contrary to `receiveCrossChainMessage`, which will only use `requiredGasLimit` in the sub-call to execute the message, this method may use all of the gas available in the transaction. Reverts if the message execution fails again on the specified message. Emits a {MessageExecuted} event if the retry is successful. Requirements: - `message` must have previously failed to execute, and matches the hash of the failed message." + }, + "retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "details": "Emits a {SendCrossChainMessage} event. Requirements: - `message` must have been previously sent. - `message` encoding must match previously sent message." + }, + "sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes))": + { + "details": "See {ITeleporterMessenger-sendCrossChainMessage} When executed, a relayer may kick off an asynchronous event to have the validators of the chain create an aggregate BLS signature of the message. Emits a {SendCrossChainMessage} event when message successfully gets sent." + }, + "sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])": + { + "details": "There is no explicit limit to the number of receipts able to be sent by a {sendSpecifiedReceipts} message because this method is intended to be used by relayers themselves to ensure their receipts get returned. There is no fee associated with the empty message, and the same relayer is expected to relay it themselves in order to claim their rewards, so it is their responsibility to ensure that the necessary gas is provided for however many receipts are being retried. These specified receipts are not removed from their corresponding receipt queue because there is no efficient way to remove a specific receipt from an arbitrary position in the queue, and it is harmless for receipts to be sent multiple times within the protocol. Emits {SendCrossChainMessage} event. Requirements: - `messageIDs` must all be valid and have existing receipts.", + "returns": + { + "_0": "The message ID of the newly sent message." + } + } + }, + "stateVariables": + { + "_receivedMessageNonces": + { + "details": "Tracks the message nonce for each message that has been received. The key is the message ID, and the value is the nonce value that was received as a part of that message. Note: the `messageNonce` values are also used to determine if a given message has been received or not." + }, + "_relayerRewardAddresses": + { + "details": "Tracks the relayer reward address for each message that has been received. The key is the message ID, and the value is the reward address provided by the deliverer of the message." + }, + "_relayerRewardAmounts": + { + "details": "Tracks the reward amounts for a given asset able to be redeemed by a given relayer. The first key is the relayer reward address, the second key is the fee token contract address, and the value is the amount of the asset redeemable by the relayer." + }, + "blockchainID": + { + "details": "Can be initialized by calling initializeBlockchainID, or will be initialized automatically on the first successful call to send or receive a message." + }, + "messageNonce": + { + "details": "Used to provide uniqueness when generating message IDs for new messages. The first message sent will use a messageNonce of 1 such that the nonce value can be used to provide replay protection for a given message ID." + }, + "receiptQueues": + { + "details": "The key is the blockchain ID of the other chain, and the value is a queue of pending receipts for messages received from that chain." + }, + "receivedFailedMessageHashes": + { + "details": "Enables retrying of failed messages with higher gas limits. Message execution is guaranteed to succeed at most once. The key is the message ID, and the value is the hash of the uniquely identified message whose execution failed." + }, + "sentMessageInfo": + { + "details": "The key is the message ID, and the value is the info for the uniquely identified message." + } + }, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"updatedFeeInfo\",\"type\":\"tuple\"}],\"name\":\"AddFeeAmount\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"blockchainID\",\"type\":\"bytes32\"}],\"name\":\"BlockchainIDInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"MessageExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"MessageExecutionFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"ReceiptReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"deliverer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rewardRedeemer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"ReceiveCrossChainMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"redeemer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"RelayerRewardsRedeemed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"name\":\"SendCrossChainMessage\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"WARP_MESSENGER\",\"outputs\":[{\"internalType\":\"contract IWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"additionalFeeAmount\",\"type\":\"uint256\"}],\"name\":\"addFeeAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"calculateMessageID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeAsset\",\"type\":\"address\"}],\"name\":\"checkRelayerRewardAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getFeeInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getMessageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getNextMessageID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getReceiptAtIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getReceiptQueueSize\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"getRelayerRewardAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initializeBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"messageReceived\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"receiptQueues\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"first\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"last\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"messageIndex\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"name\":\"receiveCrossChainMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"receivedFailedMessageHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeAsset\",\"type\":\"address\"}],\"name\":\"redeemRelayerRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"retryMessageExecution\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"receivedMessageNonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"relayerRewardAddress\",\"type\":\"address\"}],\"internalType\":\"struct TeleporterMessageReceipt[]\",\"name\":\"receipts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"struct TeleporterMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"retrySendCrossChainMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"internalType\":\"struct TeleporterMessageInput\",\"name\":\"messageInput\",\"type\":\"tuple\"}],\"name\":\"sendCrossChainMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"messageIDs\",\"type\":\"bytes32[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"}],\"name\":\"sendSpecifiedReceipts\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"}],\"name\":\"sentMessageInfo\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"custom:security-contact\":\"https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md\",\"details\":\"Implementation of the {ITeleporterMessenger} interface. This implementation is used to send messages cross chain using the IWarpMessenger precompile, and to receive messages sent from other chains. Teleporter contracts should be deployed through Nick's method of universal deployer, such that the same contract is deployed at the same address on all chains.\",\"errors\":{\"AddressEmptyCode(address)\":[{\"details\":\"There's no code at `target` (it is not a contract).\"}],\"AddressInsufficientBalance(address)\":[{\"details\":\"The ETH balance of the account is not enough to perform the operation.\"}],\"FailedInnerCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC20 token failed.\"}]},\"kind\":\"dev\",\"methods\":{\"addFeeAmount(bytes32,address,uint256)\":{\"details\":\"Both `senderNonReentrant` and `receiverNonReentrant` are used here to prevent the external call of `safeTransferFrom` from being reentrant, calling `receiveCrossChainMessage` to attribute rewards for this message, and then still adding fee amount for this message. Emits an {AddFeeAmount} event. Requirements: - `additionalFeeAmount` must be non-zero. - `message` must exist and not have been acknowledged with a receipt yet. - `feeTokenAddress` must match the fee asset contract address used in the original call to `sendCrossChainMessage`.\"},\"checkRelayerRewardAmount(address,address)\":{\"returns\":{\"_0\":\"The amount of the fee asset redeemable by the specified relayer.\"}},\"getFeeInfo(bytes32)\":{\"returns\":{\"_0\":\"The fee token address and fee amount for a the given sent message ID. If the message ID is not found, zero address and amount values are returned.\"}},\"getMessageHash(bytes32)\":{\"returns\":{\"_0\":\"The message hash\"}},\"getNextMessageID(bytes32)\":{\"returns\":{\"_0\":\"The next message ID to be used for a message sent from the contract instance.\"}},\"getReceiptAtIndex(bytes32,uint256)\":{\"returns\":{\"_0\":\"The receipt requested.\"}},\"getReceiptQueueSize(bytes32)\":{\"returns\":{\"_0\":\"Size of the given queue.\"}},\"getRelayerRewardAddress(bytes32)\":{\"returns\":{\"_0\":\"The relayer reward address for the given message.\"}},\"initializeBlockchainID()\":{\"details\":\"Emits {BlockchainIDInitialized} event.\",\"returns\":{\"_0\":\"The current blockchain ID.\"}},\"messageReceived(bytes32)\":{\"returns\":{\"_0\":\"Boolean representing if the given message has been received.\"}},\"receiveCrossChainMessage(uint32,address)\":{\"details\":\"Emits a {ReceiveCrossChainMessage} event. Re-entrancy is explicitly disallowed between receiving functions. One message is not able to receive another message. Requirements: - `relayerRewardAddress` must not be the zero address. - `messageIndex` must specify a valid warp message in the transaction's storage slots. - Valid warp message provided in storage slots, and sender address matches the address of this contract. - Teleporter message `destinationBlockchainID` must match the `blockchainID` of this contract. - Teleporter message was not previously received. - Transaction was sent by an allowed relayer for corresponding teleporter message.\"},\"redeemRelayerRewards(address)\":{\"details\":\"Requirements: - `rewardAmount` must be non-zero.\"},\"retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"details\":\"A Teleporter message has an associated `requiredGasLimit` that is used to execute the message. If the `requiredGasLimit` is too low, then the message execution will fail. This method allows for retrying the execution of a message with a higher gas limit. Contrary to `receiveCrossChainMessage`, which will only use `requiredGasLimit` in the sub-call to execute the message, this method may use all of the gas available in the transaction. Reverts if the message execution fails again on the specified message. Emits a {MessageExecuted} event if the retry is successful. Requirements: - `message` must have previously failed to execute, and matches the hash of the failed message.\"},\"retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"details\":\"Emits a {SendCrossChainMessage} event. Requirements: - `message` must have been previously sent. - `message` encoding must match previously sent message.\"},\"sendCrossChainMessage((bytes32,address,(address,uint256),uint256,address[],bytes))\":{\"details\":\"See {ITeleporterMessenger-sendCrossChainMessage} When executed, a relayer may kick off an asynchronous event to have the validators of the chain create an aggregate BLS signature of the message. Emits a {SendCrossChainMessage} event when message successfully gets sent.\"},\"sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])\":{\"details\":\"There is no explicit limit to the number of receipts able to be sent by a {sendSpecifiedReceipts} message because this method is intended to be used by relayers themselves to ensure their receipts get returned. There is no fee associated with the empty message, and the same relayer is expected to relay it themselves in order to claim their rewards, so it is their responsibility to ensure that the necessary gas is provided for however many receipts are being retried. These specified receipts are not removed from their corresponding receipt queue because there is no efficient way to remove a specific receipt from an arbitrary position in the queue, and it is harmless for receipts to be sent multiple times within the protocol. Emits {SendCrossChainMessage} event. Requirements: - `messageIDs` must all be valid and have existing receipts.\",\"returns\":{\"_0\":\"The message ID of the newly sent message.\"}}},\"stateVariables\":{\"_receivedMessageNonces\":{\"details\":\"Tracks the message nonce for each message that has been received. The key is the message ID, and the value is the nonce value that was received as a part of that message. Note: the `messageNonce` values are also used to determine if a given message has been received or not.\"},\"_relayerRewardAddresses\":{\"details\":\"Tracks the relayer reward address for each message that has been received. The key is the message ID, and the value is the reward address provided by the deliverer of the message.\"},\"_relayerRewardAmounts\":{\"details\":\"Tracks the reward amounts for a given asset able to be redeemed by a given relayer. The first key is the relayer reward address, the second key is the fee token contract address, and the value is the amount of the asset redeemable by the relayer.\"},\"blockchainID\":{\"details\":\"Can be initialized by calling initializeBlockchainID, or will be initialized automatically on the first successful call to send or receive a message.\"},\"messageNonce\":{\"details\":\"Used to provide uniqueness when generating message IDs for new messages. The first message sent will use a messageNonce of 1 such that the nonce value can be used to provide replay protection for a given message ID.\"},\"receiptQueues\":{\"details\":\"The key is the blockchain ID of the other chain, and the value is a queue of pending receipts for messages received from that chain.\"},\"receivedFailedMessageHashes\":{\"details\":\"Enables retrying of failed messages with higher gas limits. Message execution is guaranteed to succeed at most once. The key is the message ID, and the value is the hash of the uniquely identified message whose execution failed.\"},\"sentMessageInfo\":{\"details\":\"The key is the message ID, and the value is the info for the uniquely identified message.\"}},\"version\":1},\"userdoc\":{\"events\":{\"AddFeeAmount(bytes32,(address,uint256))\":{\"notice\":\"Emitted when an additional fee amount is added to a Teleporter message that had previously been sent, but not yet delivered to the destination chain.\"},\"BlockchainIDInitialized(bytes32)\":{\"notice\":\"Emitted when the blockchain ID of the contract instance is initialized using the Warp precompile.\"},\"MessageExecuted(bytes32,bytes32)\":{\"notice\":\"Emitted when a Teleporter message is successfully executed with the specified destination address and message call data. This can occur either when the message is initially received, or on a retry attempt. Each message received can be executed successfully at most once.\"},\"MessageExecutionFailed(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Emitted when a Teleporter message is being delivered on the destination chain to an address, but message execution fails. Failed messages can then be retried with `retryMessageExecution`\"},\"ReceiptReceived(bytes32,bytes32,address,(address,uint256))\":{\"notice\":\"Emitted when a receipt is marked as received on the source chain that sent the corresponding Teleporter message.\"},\"ReceiveCrossChainMessage(bytes32,bytes32,address,address,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Emitted when a TeleporterMessage is successfully received.\"},\"RelayerRewardsRedeemed(address,address,uint256)\":{\"notice\":\"Emitted when an account redeems accumulated relayer rewards.\"},\"SendCrossChainMessage(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes),(address,uint256))\":{\"notice\":\"Emitted when sending a Teleporter message cross-chain.\"}},\"kind\":\"user\",\"methods\":{\"WARP_MESSENGER()\":{\"notice\":\"Warp precompile used for sending and receiving Warp messages.\"},\"addFeeAmount(bytes32,address,uint256)\":{\"notice\":\"Adds the additional fee amount to the amount to be paid to the relayer that delivers the given message ID to the destination chain.\"},\"blockchainID()\":{\"notice\":\"The blockchain ID of the chain the contract is deployed on.\"},\"calculateMessageID(bytes32,bytes32,uint256)\":{\"notice\":\"Calculates the message ID for a message sent from this contract instance with the given source blockchain ID, destination blockchain ID, and message nonce.\"},\"checkRelayerRewardAmount(address,address)\":{\"notice\":\"Gets the current reward amount of a given fee asset that is redeemable by the given relayer.\"},\"getFeeInfo(bytes32)\":{\"notice\":\"Gets the fee token address and amount for a given sent message.\"},\"getMessageHash(bytes32)\":{\"notice\":\"Gets the hash of a given message stored in the EVM state, if the message exists.\"},\"getNextMessageID(bytes32)\":{\"notice\":\"Gets the next message ID to be used for a message sent from the contract instance.\"},\"getReceiptAtIndex(bytes32,uint256)\":{\"notice\":\"Gets the receipt at the given index in the queue for the given source chain ID.\"},\"getReceiptQueueSize(bytes32)\":{\"notice\":\"Gets the number of receipts that are waiting to be sent to the given source chain ID.\"},\"getRelayerRewardAddress(bytes32)\":{\"notice\":\"Returns the address the relayer reward should be sent to on the source chain for a given message, assuming that the message has already been delivered.\"},\"initializeBlockchainID()\":{\"notice\":\"If not already set, initializes blockchainID by getting the current blockchain ID value from the Warp precompile.\"},\"messageNonce()\":{\"notice\":\"A monotonically incremented integer tracking the total number of messages sent by this TeleporterMessenger contract.\"},\"messageReceived(bytes32)\":{\"notice\":\"Checks whether or not the given message has been received by this chain.\"},\"receiptQueues(bytes32)\":{\"notice\":\"Tracks the outstanding receipts to send back to a given chain in subsequent messages sent to that chain.\"},\"receiveCrossChainMessage(uint32,address)\":{\"notice\":\"Receives a cross-chain message, and marks the `relayerRewardAddress` for fee reward for a successful delivery.\"},\"receivedFailedMessageHashes(bytes32)\":{\"notice\":\"Tracks the hash of messages that have been received but have never succeeded in execution.\"},\"redeemRelayerRewards(address)\":{\"notice\":\"Sends any fee amount rewards for the given fee asset out to the caller.\"},\"retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Retries the execution of a previously delivered message by verifying the payload matches the hash of the payload originally delivered, and calling the destination address again.\"},\"retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))\":{\"notice\":\"Called by transactions to retry the sending of a cross-chain message.\"},\"sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])\":{\"notice\":\"Sends the receipts for the given `messageIDs`.\"},\"sentMessageInfo(bytes32)\":{\"notice\":\"Tracks the message hash and fee information for each message sent that has yet to be acknowledged with a receipt.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/contracts/teleporter/TeleporterMessenger.sol\":\"TeleporterMessenger\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/contracts/subnet-evm/IWarpMessenger.sol\":{\"keccak256\":\"0xda93e4a651466547d22b5574556053c188df273614549c9e2a527036b6b29652\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c4e7584e2ce261e9b8d9c2ed4c22acc9a086785c0891e8dbdad4cfba01dc14eb\",\"dweb:/ipfs/QmPZo4N5FRasJH5QLNbpDXyj4BfqhWD3fwsVjJmWu517Nk\"]},\"icm-contracts/contracts/teleporter/ITeleporterMessenger.sol\":{\"keccak256\":\"0x132bfcef25900fa05c6e7319de788502d3616646577ea2d58fb303e00f1bc715\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://35a18c6f77f4efbbbb5c389e149d4eb6aa631fdaf7e8412e925dbb97efc532c7\",\"dweb:/ipfs/QmYi9mAqGSeC8SH2GJCtVqnhhhziFK5RQ21NirvGrBoton\"]},\"icm-contracts/contracts/teleporter/ITeleporterReceiver.sol\":{\"keccak256\":\"0x3a3cd5b52193d940d634d4754f51f423e75c927a86d3eb91d5a583eb54ef9cd6\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://96843ce304eaedceea3b2b5aca57be97fc200e58533045c544ad7bba62223e86\",\"dweb:/ipfs/QmYMvWLqpRqENKrKwhLTcWrQbqtdo35zLJpgMxzKE2ZznV\"]},\"icm-contracts/contracts/teleporter/ReceiptQueue.sol\":{\"keccak256\":\"0x79bbf8faa818cc8834034e7ae37e38f53fdff71540277e73c06a68dfa9c2e45e\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://076fbb8461c4758f6b5c3e8a91607292cdf95a1b7fb030448c288932746a1434\",\"dweb:/ipfs/QmcjxZZW4HnAbcWB1EHsT6Tw7V5ChJ4YQu8Lb7b7VzoRhp\"]},\"icm-contracts/contracts/teleporter/TeleporterMessenger.sol\":{\"keccak256\":\"0x1a0f75394d1ec4d8f76495182c57cbb090eb29d47b859be9b0c0fd694f7d35ce\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://880a026a2ac63d3f0f975d5d56b2c1b34931b49cc423a02d8813d3326802c6bb\",\"dweb:/ipfs/QmPbum3WsC2ApunthuvyE52DgyxVaxDusAvpsGMpRfhpN1\"]},\"icm-contracts/contracts/utilities/ReentrancyGuards.sol\":{\"keccak256\":\"0x934c47e5ea5a9523bdafd60285efb94aae4fc77b4c285c47b7cf44c1b0edfe79\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://9098ee1bcc7d01844fd474f032189fdfc1701233a96f616f7ac3fa8fd316fb63\",\"dweb:/ipfs/QmcDTZUZZsB6qFPGmjcBNHv8c4Xa3bu7YcSZiYNZmvDKEN\"]},\"icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol\":{\"keccak256\":\"0x485867dc46af4ee0812024758b2f3493b3efc15f8ba23d73223dd847b04c8018\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://2b9b29d8ee033a2ed8dd1bdb024027704f1180a1316732cb3d3874898d277736\",\"dweb:/ipfs/QmR257FurAqL57rzY1BVJhxCS6yndrBow1J4hMHCwfcvyA\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d\",\"dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3036b3a83b7c48f96641f2a9002b9f2dcb6a5958dd670894ada21ae8229b3d0\",\"dweb:/ipfs/QmUNfSBdoVtjhETaUJCYcaC7pTMgbhht926tJ2uXJbiVd3\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245\",\"dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ece9f0b9c8daca08c76b6b5405a6446b6f73b3a15fab7ff56e296cbd4a2c875\",\"dweb:/ipfs/QmQyRpyPRL5SQuAgj6SHmbir3foX65FJjbVTTQrA2EFg6L\"]}},\"version\":1}", + "userdoc": + { + "events": + { + "AddFeeAmount(bytes32,(address,uint256))": + { + "notice": "Emitted when an additional fee amount is added to a Teleporter message that had previously been sent, but not yet delivered to the destination chain." + }, + "BlockchainIDInitialized(bytes32)": + { + "notice": "Emitted when the blockchain ID of the contract instance is initialized using the Warp precompile." + }, + "MessageExecuted(bytes32,bytes32)": + { + "notice": "Emitted when a Teleporter message is successfully executed with the specified destination address and message call data. This can occur either when the message is initially received, or on a retry attempt. Each message received can be executed successfully at most once." + }, + "MessageExecutionFailed(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Emitted when a Teleporter message is being delivered on the destination chain to an address, but message execution fails. Failed messages can then be retried with `retryMessageExecution`" + }, + "ReceiptReceived(bytes32,bytes32,address,(address,uint256))": + { + "notice": "Emitted when a receipt is marked as received on the source chain that sent the corresponding Teleporter message." + }, + "ReceiveCrossChainMessage(bytes32,bytes32,address,address,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Emitted when a TeleporterMessage is successfully received." + }, + "RelayerRewardsRedeemed(address,address,uint256)": + { + "notice": "Emitted when an account redeems accumulated relayer rewards." + }, + "SendCrossChainMessage(bytes32,bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes),(address,uint256))": + { + "notice": "Emitted when sending a Teleporter message cross-chain." + } + }, + "kind": "user", + "methods": + { + "WARP_MESSENGER()": + { + "notice": "Warp precompile used for sending and receiving Warp messages." + }, + "addFeeAmount(bytes32,address,uint256)": + { + "notice": "Adds the additional fee amount to the amount to be paid to the relayer that delivers the given message ID to the destination chain." + }, + "blockchainID()": + { + "notice": "The blockchain ID of the chain the contract is deployed on." + }, + "calculateMessageID(bytes32,bytes32,uint256)": + { + "notice": "Calculates the message ID for a message sent from this contract instance with the given source blockchain ID, destination blockchain ID, and message nonce." + }, + "checkRelayerRewardAmount(address,address)": + { + "notice": "Gets the current reward amount of a given fee asset that is redeemable by the given relayer." + }, + "getFeeInfo(bytes32)": + { + "notice": "Gets the fee token address and amount for a given sent message." + }, + "getMessageHash(bytes32)": + { + "notice": "Gets the hash of a given message stored in the EVM state, if the message exists." + }, + "getNextMessageID(bytes32)": + { + "notice": "Gets the next message ID to be used for a message sent from the contract instance." + }, + "getReceiptAtIndex(bytes32,uint256)": + { + "notice": "Gets the receipt at the given index in the queue for the given source chain ID." + }, + "getReceiptQueueSize(bytes32)": + { + "notice": "Gets the number of receipts that are waiting to be sent to the given source chain ID." + }, + "getRelayerRewardAddress(bytes32)": + { + "notice": "Returns the address the relayer reward should be sent to on the source chain for a given message, assuming that the message has already been delivered." + }, + "initializeBlockchainID()": + { + "notice": "If not already set, initializes blockchainID by getting the current blockchain ID value from the Warp precompile." + }, + "messageNonce()": + { + "notice": "A monotonically incremented integer tracking the total number of messages sent by this TeleporterMessenger contract." + }, + "messageReceived(bytes32)": + { + "notice": "Checks whether or not the given message has been received by this chain." + }, + "receiptQueues(bytes32)": + { + "notice": "Tracks the outstanding receipts to send back to a given chain in subsequent messages sent to that chain." + }, + "receiveCrossChainMessage(uint32,address)": + { + "notice": "Receives a cross-chain message, and marks the `relayerRewardAddress` for fee reward for a successful delivery." + }, + "receivedFailedMessageHashes(bytes32)": + { + "notice": "Tracks the hash of messages that have been received but have never succeeded in execution." + }, + "redeemRelayerRewards(address)": + { + "notice": "Sends any fee amount rewards for the given fee asset out to the caller." + }, + "retryMessageExecution(bytes32,(uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Retries the execution of a previously delivered message by verifying the payload matches the hash of the payload originally delivered, and calling the destination address again." + }, + "retrySendCrossChainMessage((uint256,address,bytes32,address,uint256,address[],(uint256,address)[],bytes))": + { + "notice": "Called by transactions to retry the sending of a cross-chain message." + }, + "sendSpecifiedReceipts(bytes32,bytes32[],(address,uint256),address[])": + { + "notice": "Sends the receipts for the given `messageIDs`." + }, + "sentMessageInfo(bytes32)": + { + "notice": "Tracks the message hash and fee information for each message sent that has yet to be acknowledged with a receipt." + } + }, + "version": 1 + } + }, + "icm-contracts/contracts/utilities/ReentrancyGuards.sol:ReentrancyGuards": + { + "abi": [], + "bin": "", + "devdoc": + { + "custom:security-contact": "https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md", + "details": "Abstract contract that helps implement reentrancy guards between functions for sending and receiving. Consecutive calls for sending functions should work together, same for receive functions, but recursive calls should be detected as a reentrancy and revert. Calls between send and receive functions should also be allowed, but not in the case it ends up being a recursive send or receive call. For example the following should fail: send -> receive -> send.", + "kind": "dev", + "methods": {}, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"custom:security-contact\":\"https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md\",\"details\":\"Abstract contract that helps implement reentrancy guards between functions for sending and receiving. Consecutive calls for sending functions should work together, same for receive functions, but recursive calls should be detected as a reentrancy and revert. Calls between send and receive functions should also be allowed, but not in the case it ends up being a recursive send or receive call. For example the following should fail: send -> receive -> send.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/contracts/utilities/ReentrancyGuards.sol\":\"ReentrancyGuards\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/contracts/utilities/ReentrancyGuards.sol\":{\"keccak256\":\"0x934c47e5ea5a9523bdafd60285efb94aae4fc77b4c285c47b7cf44c1b0edfe79\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://9098ee1bcc7d01844fd474f032189fdfc1701233a96f616f7ac3fa8fd316fb63\",\"dweb:/ipfs/QmcDTZUZZsB6qFPGmjcBNHv8c4Xa3bu7YcSZiYNZmvDKEN\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol:SafeERC20TransferFrom": + { + "abi": [], + "bin": "60556032600b8282823980515f1a607314602657634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea264697066735822122085a9cb74134c8db5f8920d1103e17199b6046c34c4b6a8b4251d87996bac870964736f6c63430008190033", + "devdoc": + { + "custom:security-contact": "https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md", + "details": "Provides a wrapper used for calling an ERC20 transferFrom method to receive tokens to a contract from msg.sender. Checks the balance of the contract using the library before and after the call to safeTransferFrom, and returns balance increase. Designed for safely handling ERC20 \"fee on transfer\" and \"burn on transfer\" implementations. Note: A reentrancy guard must always be used when calling token.safeTransferFrom in order to prevent against possible \"before-after\" pattern vulnerabilities.", + "kind": "dev", + "methods": {}, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"custom:security-contact\":\"https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md\",\"details\":\"Provides a wrapper used for calling an ERC20 transferFrom method to receive tokens to a contract from msg.sender. Checks the balance of the contract using the library before and after the call to safeTransferFrom, and returns balance increase. Designed for safely handling ERC20 \\\"fee on transfer\\\" and \\\"burn on transfer\\\" implementations. Note: A reentrancy guard must always be used when calling token.safeTransferFrom in order to prevent against possible \\\"before-after\\\" pattern vulnerabilities.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol\":\"SafeERC20TransferFrom\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol\":{\"keccak256\":\"0x485867dc46af4ee0812024758b2f3493b3efc15f8ba23d73223dd847b04c8018\",\"license\":\"LicenseRef-Ecosystem\",\"urls\":[\"bzz-raw://2b9b29d8ee033a2ed8dd1bdb024027704f1180a1316732cb3d3874898d277736\",\"dweb:/ipfs/QmR257FurAqL57rzY1BVJhxCS6yndrBow1J4hMHCwfcvyA\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d\",\"dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3036b3a83b7c48f96641f2a9002b9f2dcb6a5958dd670894ada21ae8229b3d0\",\"dweb:/ipfs/QmUNfSBdoVtjhETaUJCYcaC7pTMgbhht926tJ2uXJbiVd3\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245\",\"dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol:IERC20": + { + "abi": + [ + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": + [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "", + "devdoc": + { + "details": "Interface of the ERC20 standard as defined in the EIP.", + "events": + { + "Approval(address,address,uint256)": + { + "details": "Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance." + }, + "Transfer(address,address,uint256)": + { + "details": "Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero." + } + }, + "kind": "dev", + "methods": + { + "allowance(address,address)": + { + "details": "Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called." + }, + "approve(address,uint256)": + { + "details": "Sets a `value` amount of tokens as the allowance of `spender` over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an {Approval} event." + }, + "balanceOf(address)": + { + "details": "Returns the value of tokens owned by `account`." + }, + "totalSupply()": + { + "details": "Returns the value of tokens in existence." + }, + "transfer(address,uint256)": + { + "details": "Moves a `value` amount of tokens from the caller's account to `to`. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event." + }, + "transferFrom(address,address,uint256)": + { + "details": "Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism. `value` is then deducted from the caller's allowance. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event." + } + }, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC20 standard as defined in the EIP.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through {transferFrom}. This is zero by default. This value changes when {approve} or {transferFrom} are called.\"},\"approve(address,uint256)\":{\"details\":\"Sets a `value` amount of tokens as the allowance of `spender` over the caller's tokens. Returns a boolean value indicating whether the operation succeeded. IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the value of tokens owned by `account`.\"},\"totalSupply()\":{\"details\":\"Returns the value of tokens in existence.\"},\"transfer(address,uint256)\":{\"details\":\"Moves a `value` amount of tokens from the caller's account to `to`. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism. `value` is then deducted from the caller's allowance. Returns a boolean value indicating whether the operation succeeded. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":\"IERC20\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol:IERC20Permit": + { + "abi": + [ + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": + [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": + [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "", + "devdoc": + { + "details": "Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't need to send a transaction, and thus is not required to hold Ether at all. ==== Security Considerations There are two important considerations concerning the use of `permit`. The first is that a valid permit signature expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be considered as an intention to spend the allowance in any specific way. The second is that because permits have built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be generally recommended is: ```solidity function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} doThing(..., value); } function doThing(..., uint256 value) public { token.safeTransferFrom(msg.sender, address(this), value); ... } ``` Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also {SafeERC20-safeTransferFrom}). Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so contracts should have entry points that don't rely on permit.", + "kind": "dev", + "methods": + { + "DOMAIN_SEPARATOR()": + { + "details": "Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}." + }, + "nonces(address)": + { + "details": "Returns the current nonce for `owner`. This value must be included whenever a signature is generated for {permit}. Every successful call to {permit} increases ``owner``'s nonce by one. This prevents a signature from being used multiple times." + }, + "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": + { + "details": "Sets `value` as the allowance of `spender` over ``owner``'s tokens, given ``owner``'s signed approval. IMPORTANT: The same issues {IERC20-approve} has related to transaction ordering also apply here. Emits an {Approval} event. Requirements: - `spender` cannot be the zero address. - `deadline` must be a timestamp in the future. - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` over the EIP712-formatted function arguments. - the signature must use ``owner``'s current nonce (see {nonces}). For more information on the signature format, see the https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section]. CAUTION: See Security Considerations above." + } + }, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't need to send a transaction, and thus is not required to hold Ether at all. ==== Security Considerations There are two important considerations concerning the use of `permit`. The first is that a valid permit signature expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be considered as an intention to spend the allowance in any specific way. The second is that because permits have built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be generally recommended is: ```solidity function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} doThing(..., value); } function doThing(..., uint256 value) public { token.safeTransferFrom(msg.sender, address(this), value); ... } ``` Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also {SafeERC20-safeTransferFrom}). Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so contracts should have entry points that don't rely on permit.\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\"},\"nonces(address)\":{\"details\":\"Returns the current nonce for `owner`. This value must be included whenever a signature is generated for {permit}. Every successful call to {permit} increases ``owner``'s nonce by one. This prevents a signature from being used multiple times.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"Sets `value` as the allowance of `spender` over ``owner``'s tokens, given ``owner``'s signed approval. IMPORTANT: The same issues {IERC20-approve} has related to transaction ordering also apply here. Emits an {Approval} event. Requirements: - `spender` cannot be the zero address. - `deadline` must be a timestamp in the future. - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` over the EIP712-formatted function arguments. - the signature must use ``owner``'s current nonce (see {nonces}). For more information on the signature format, see the https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section]. CAUTION: See Security Considerations above.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":\"IERC20Permit\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d\",\"dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol:SafeERC20": + { + "abi": + [ + { + "inputs": + [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "currentAllowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requestedDecrease", + "type": "uint256" + } + ], + "name": "SafeERC20FailedDecreaseAllowance", + "type": "error" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + } + ], + "bin": "60556032600b8282823980515f1a607314602657634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220c56369bd4b973ad3d8aebbf6e370284dcbc9090d7e5b1f7fd751b99262cbd7bb64736f6c63430008190033", + "devdoc": + { + "details": "Wrappers around ERC20 operations that throw on failure (when the token contract returns false). Tokens that return no value (and instead revert or throw on failure) are also supported, non-reverting calls are assumed to be successful. To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, which allows you to call the safe operations as `token.safeTransfer(...)`, etc.", + "errors": + { + "SafeERC20FailedDecreaseAllowance(address,uint256,uint256)": + [ + { + "details": "Indicates a failed `decreaseAllowance` request." + } + ], + "SafeERC20FailedOperation(address)": + [ + { + "details": "An operation with an ERC20 token failed." + } + ] + }, + "kind": "dev", + "methods": {}, + "title": "SafeERC20", + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"currentAllowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestedDecrease\",\"type\":\"uint256\"}],\"name\":\"SafeERC20FailedDecreaseAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"}],\"devdoc\":{\"details\":\"Wrappers around ERC20 operations that throw on failure (when the token contract returns false). Tokens that return no value (and instead revert or throw on failure) are also supported, non-reverting calls are assumed to be successful. To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\",\"errors\":{\"SafeERC20FailedDecreaseAllowance(address,uint256,uint256)\":[{\"details\":\"Indicates a failed `decreaseAllowance` request.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC20 token failed.\"}]},\"kind\":\"dev\",\"methods\":{},\"title\":\"SafeERC20\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":\"SafeERC20\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0ea104e577e63faea3b69c415637e99e755dcbf64c5833d7140c35a714d6d90c\",\"dweb:/ipfs/Qmau6x4Ns9XdyynRCNNp3RhLqijJjFm7z5fyZazfYFGYdq\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"keccak256\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f5196ec75139918c6c7bb4251b36395e668f1fa6d206beba7e7520e74913940d\",\"dweb:/ipfs/QmSyqjksXxmm2mCG6qRd1yuwLykypkSVBbnBnGqJRcuJMi\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3036b3a83b7c48f96641f2a9002b9f2dcb6a5958dd670894ada21ae8229b3d0\",\"dweb:/ipfs/QmUNfSBdoVtjhETaUJCYcaC7pTMgbhht926tJ2uXJbiVd3\"]},\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245\",\"dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol:Address": + { + "abi": + [ + { + "inputs": + [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + } + ], + "bin": "60556032600b8282823980515f1a607314602657634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220bfe2bbd96fcffe9ff96fb3b127c7ddce66fceebdaa1d9ac5d7cb657e670b3ad864736f6c63430008190033", + "devdoc": + { + "details": "Collection of functions related to the address type", + "errors": + { + "AddressEmptyCode(address)": + [ + { + "details": "There's no code at `target` (it is not a contract)." + } + ], + "AddressInsufficientBalance(address)": + [ + { + "details": "The ETH balance of the account is not enough to perform the operation." + } + ], + "FailedInnerCall()": + [ + { + "details": "A call to an address target failed. The target may have reverted." + } + ] + }, + "kind": "dev", + "methods": {}, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"}],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"errors\":{\"AddressEmptyCode(address)\":[{\"details\":\"There's no code at `target` (it is not a contract).\"}],\"AddressInsufficientBalance(address)\":[{\"details\":\"The ETH balance of the account is not enough to perform the operation.\"}],\"FailedInnerCall()\":[{\"details\":\"A call to an address target failed. The target may have reverted.\"}]},\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol\":\"Address\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol\":{\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b7bd24e224f67f65bfadf85dc2929fa965456bb2415478bd0125471b5ce35245\",\"dweb:/ipfs/QmRaydGr8BTHs1kvaZfsNU69pKzUAGFrvABn1KiRSbE51y\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol:Math": + { + "abi": + [ + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + } + ], + "bin": "60556032600b8282823980515f1a607314602657634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220facb805e315c2bb4ac0d2c643b821080c5923da75a35d1855fa107c2c51c6fb964736f6c63430008190033", + "devdoc": + { + "details": "Standard math utilities missing in the Solidity language.", + "errors": + { + "MathOverflowedMulDiv()": + [ + { + "details": "Muldiv operation overflow." + } + ] + }, + "kind": "dev", + "methods": {}, + "version": 1 + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"MathOverflowedMulDiv\",\"type\":\"error\"}],\"devdoc\":{\"details\":\"Standard math utilities missing in the Solidity language.\",\"errors\":{\"MathOverflowedMulDiv()\":[{\"details\":\"Muldiv operation overflow.\"}]},\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":\"Math\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@forge-std=icm-contracts/lib/forge-std/src\",\":@mocks=icm-contracts/contracts/mocks\",\":@openzeppelin/contracts-upgradeable/=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts/\",\":@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts\",\":@openzeppelin/contracts/=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/\",\":@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts\",\":@subnet-evm=icm-contracts/contracts/subnet-evm\",\":@teleporter=icm-contracts/contracts/teleporter\",\":@utilities=icm-contracts/contracts/utilities\"]},\"sources\":{\"icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ece9f0b9c8daca08c76b6b5405a6446b6f73b3a15fab7ff56e296cbd4a2c875\",\"dweb:/ipfs/QmQyRpyPRL5SQuAgj6SHmbir3foX65FJjbVTTQrA2EFg6L\"]}},\"version\":1}", + "userdoc": + { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "sourceList": + [ + "icm-contracts/contracts/subnet-evm/IWarpMessenger.sol", + "icm-contracts/contracts/teleporter/ITeleporterMessenger.sol", + "icm-contracts/contracts/teleporter/ITeleporterReceiver.sol", + "icm-contracts/contracts/teleporter/ReceiptQueue.sol", + "icm-contracts/contracts/teleporter/TeleporterMessenger.sol", + "icm-contracts/contracts/utilities/ReentrancyGuards.sol", + "icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol", + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol", + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol", + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol", + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol", + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol" + ], + "sources": + { + "icm-contracts/contracts/subnet-evm/IWarpMessenger.sol": + { + "AST": + { + "absolutePath": "icm-contracts/contracts/subnet-evm/IWarpMessenger.sol", + "exportedSymbols": + { + "IWarpMessenger": + [ + 1389 + ], + "WarpBlockHash": + [ + 1348 + ], + "WarpMessage": + [ + 1343 + ] + }, + "id": 1390, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1336, + "literals": + [ + "solidity", + "0.8", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "33:23:0" + }, + { + "canonicalName": "WarpMessage", + "id": 1343, + "members": + [ + { + "constant": false, + "id": 1338, + "mutability": "mutable", + "name": "sourceChainID", + "nameLocation": "91:13:0", + "nodeType": "VariableDeclaration", + "scope": 1343, + "src": "83:21:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1337, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "83:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1340, + "mutability": "mutable", + "name": "originSenderAddress", + "nameLocation": "118:19:0", + "nodeType": "VariableDeclaration", + "scope": 1343, + "src": "110:27:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1339, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "110:7:0", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1342, + "mutability": "mutable", + "name": "payload", + "nameLocation": "149:7:0", + "nodeType": "VariableDeclaration", + "scope": 1343, + "src": "143:13:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1341, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "143:5:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "name": "WarpMessage", + "nameLocation": "65:11:0", + "nodeType": "StructDefinition", + "scope": 1390, + "src": "58:101:0", + "visibility": "public" + }, + { + "canonicalName": "WarpBlockHash", + "id": 1348, + "members": + [ + { + "constant": false, + "id": 1345, + "mutability": "mutable", + "name": "sourceChainID", + "nameLocation": "196:13:0", + "nodeType": "VariableDeclaration", + "scope": 1348, + "src": "188:21:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1344, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "188:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1347, + "mutability": "mutable", + "name": "blockHash", + "nameLocation": "223:9:0", + "nodeType": "VariableDeclaration", + "scope": 1348, + "src": "215:17:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1346, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "215:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "name": "WarpBlockHash", + "nameLocation": "168:13:0", + "nodeType": "StructDefinition", + "scope": 1390, + "src": "161:74:0", + "visibility": "public" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "IWarpMessenger", + "contractDependencies": [], + "contractKind": "interface", + "fullyImplemented": false, + "id": 1389, + "linearizedBaseContracts": + [ + 1389 + ], + "name": "IWarpMessenger", + "nameLocation": "247:14:0", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "anonymous": false, + "eventSelector": "56600c567728a800c0aa927500f831cb451df66a7af570eb4df4dfbf4674887d", + "id": 1356, + "name": "SendWarpMessage", + "nameLocation": "274:15:0", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1355, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1350, + "indexed": true, + "mutability": "mutable", + "name": "sender", + "nameLocation": "306:6:0", + "nodeType": "VariableDeclaration", + "scope": 1356, + "src": "290:22:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1349, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "290:7:0", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1352, + "indexed": true, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "330:9:0", + "nodeType": "VariableDeclaration", + "scope": 1356, + "src": "314:25:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1351, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "314:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1354, + "indexed": false, + "mutability": "mutable", + "name": "message", + "nameLocation": "347:7:0", + "nodeType": "VariableDeclaration", + "scope": 1356, + "src": "341:13:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1353, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "341:5:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "289:66:0" + }, + "src": "268:88:0" + }, + { + "functionSelector": "ee5b48eb", + "id": 1363, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "sendWarpMessage", + "nameLocation": "907:15:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1359, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1358, + "mutability": "mutable", + "name": "payload", + "nameLocation": "947:7:0", + "nodeType": "VariableDeclaration", + "scope": 1363, + "src": "932:22:0", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1357, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "932:5:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "922:38:0" + }, + "returnParameters": + { + "id": 1362, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1361, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "987:9:0", + "nodeType": "VariableDeclaration", + "scope": 1363, + "src": "979:17:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1360, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "979:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "978:19:0" + }, + "scope": 1389, + "src": "898:100:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "functionSelector": "6f825350", + "id": 1373, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getVerifiedWarpMessage", + "nameLocation": "1334:22:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1366, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1365, + "mutability": "mutable", + "name": "index", + "nameLocation": "1373:5:0", + "nodeType": "VariableDeclaration", + "scope": 1373, + "src": "1366:12:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": + { + "id": 1364, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "1366:6:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "visibility": "internal" + } + ], + "src": "1356:28:0" + }, + "returnParameters": + { + "id": 1372, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1369, + "mutability": "mutable", + "name": "message", + "nameLocation": "1429:7:0", + "nodeType": "VariableDeclaration", + "scope": 1373, + "src": "1408:28:0", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_calldata_ptr", + "typeString": "struct WarpMessage" + }, + "typeName": + { + "id": 1368, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1367, + "name": "WarpMessage", + "nameLocations": + [ + "1408:11:0" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1343, + "src": "1408:11:0" + }, + "referencedDeclaration": 1343, + "src": "1408:11:0", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_storage_ptr", + "typeString": "struct WarpMessage" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1371, + "mutability": "mutable", + "name": "valid", + "nameLocation": "1443:5:0", + "nodeType": "VariableDeclaration", + "scope": 1373, + "src": "1438:10:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 1370, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1438:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "1407:42:0" + }, + "scope": 1389, + "src": "1325:125:0", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "functionSelector": "ce7f5929", + "id": 1383, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getVerifiedWarpBlockHash", + "nameLocation": "1807:24:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1376, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1375, + "mutability": "mutable", + "name": "index", + "nameLocation": "1848:5:0", + "nodeType": "VariableDeclaration", + "scope": 1383, + "src": "1841:12:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": + { + "id": 1374, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "1841:6:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "visibility": "internal" + } + ], + "src": "1831:28:0" + }, + "returnParameters": + { + "id": 1382, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1379, + "mutability": "mutable", + "name": "warpBlockHash", + "nameLocation": "1906:13:0", + "nodeType": "VariableDeclaration", + "scope": 1383, + "src": "1883:36:0", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpBlockHash_$1348_calldata_ptr", + "typeString": "struct WarpBlockHash" + }, + "typeName": + { + "id": 1378, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1377, + "name": "WarpBlockHash", + "nameLocations": + [ + "1883:13:0" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1348, + "src": "1883:13:0" + }, + "referencedDeclaration": 1348, + "src": "1883:13:0", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpBlockHash_$1348_storage_ptr", + "typeString": "struct WarpBlockHash" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1381, + "mutability": "mutable", + "name": "valid", + "nameLocation": "1926:5:0", + "nodeType": "VariableDeclaration", + "scope": 1383, + "src": "1921:10:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 1380, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1921:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "1882:50:0" + }, + "scope": 1389, + "src": "1798:135:0", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "functionSelector": "4213cf78", + "id": 1388, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getBlockchainID", + "nameLocation": "2175:15:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1384, + "nodeType": "ParameterList", + "parameters": [], + "src": "2190:2:0" + }, + "returnParameters": + { + "id": 1387, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1386, + "mutability": "mutable", + "name": "blockchainID", + "nameLocation": "2224:12:0", + "nodeType": "VariableDeclaration", + "scope": 1388, + "src": "2216:20:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1385, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2216:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "2215:22:0" + }, + "scope": 1389, + "src": "2166:72:0", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + } + ], + "scope": 1390, + "src": "237:2003:0", + "usedErrors": [], + "usedEvents": + [ + 1356 + ] + } + ], + "src": "33:2208:0" + }, + "id": 0 + }, + "icm-contracts/contracts/teleporter/ITeleporterMessenger.sol": + { + "AST": + { + "absolutePath": "icm-contracts/contracts/teleporter/ITeleporterMessenger.sol", + "exportedSymbols": + { + "ITeleporterMessenger": + [ + 1653 + ], + "TeleporterFeeInfo": + [ + 1436 + ], + "TeleporterMessage": + [ + 1431 + ], + "TeleporterMessageInput": + [ + 1411 + ], + "TeleporterMessageReceipt": + [ + 1396 + ] + }, + "id": 1654, + "license": "LicenseRef-Ecosystem", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1391, + "literals": + [ + "solidity", + "0.8", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "145:23:1" + }, + { + "canonicalName": "TeleporterMessageReceipt", + "id": 1396, + "members": + [ + { + "constant": false, + "id": 1393, + "mutability": "mutable", + "name": "receivedMessageNonce", + "nameLocation": "357:20:1", + "nodeType": "VariableDeclaration", + "scope": 1396, + "src": "349:28:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1392, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "349:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1395, + "mutability": "mutable", + "name": "relayerRewardAddress", + "nameLocation": "391:20:1", + "nodeType": "VariableDeclaration", + "scope": 1396, + "src": "383:28:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1394, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "383:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "name": "TeleporterMessageReceipt", + "nameLocation": "318:24:1", + "nodeType": "StructDefinition", + "scope": 1654, + "src": "311:103:1", + "visibility": "public" + }, + { + "canonicalName": "TeleporterMessageInput", + "id": 1411, + "members": + [ + { + "constant": false, + "id": 1398, + "mutability": "mutable", + "name": "destinationBlockchainID", + "nameLocation": "832:23:1", + "nodeType": "VariableDeclaration", + "scope": 1411, + "src": "824:31:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1397, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "824:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1400, + "mutability": "mutable", + "name": "destinationAddress", + "nameLocation": "869:18:1", + "nodeType": "VariableDeclaration", + "scope": 1411, + "src": "861:26:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1399, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "861:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1403, + "mutability": "mutable", + "name": "feeInfo", + "nameLocation": "911:7:1", + "nodeType": "VariableDeclaration", + "scope": 1411, + "src": "893:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 1402, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1401, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "893:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "893:17:1" + }, + "referencedDeclaration": 1436, + "src": "893:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1405, + "mutability": "mutable", + "name": "requiredGasLimit", + "nameLocation": "932:16:1", + "nodeType": "VariableDeclaration", + "scope": 1411, + "src": "924:24:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1404, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "924:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1408, + "mutability": "mutable", + "name": "allowedRelayerAddresses", + "nameLocation": "964:23:1", + "nodeType": "VariableDeclaration", + "scope": 1411, + "src": "954:33:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + }, + "typeName": + { + "baseType": + { + "id": 1406, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "954:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 1407, + "nodeType": "ArrayTypeName", + "src": "954:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1410, + "mutability": "mutable", + "name": "message", + "nameLocation": "999:7:1", + "nodeType": "VariableDeclaration", + "scope": 1411, + "src": "993:13:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1409, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "993:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "name": "TeleporterMessageInput", + "nameLocation": "795:22:1", + "nodeType": "StructDefinition", + "scope": 1654, + "src": "788:221:1", + "visibility": "public" + }, + { + "canonicalName": "TeleporterMessage", + "id": 1431, + "members": + [ + { + "constant": false, + "id": 1413, + "mutability": "mutable", + "name": "messageNonce", + "nameLocation": "1139:12:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1131:20:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1412, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1131:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1415, + "mutability": "mutable", + "name": "originSenderAddress", + "nameLocation": "1165:19:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1157:27:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1414, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1157:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1417, + "mutability": "mutable", + "name": "destinationBlockchainID", + "nameLocation": "1198:23:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1190:31:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1416, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1190:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1419, + "mutability": "mutable", + "name": "destinationAddress", + "nameLocation": "1235:18:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1227:26:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1418, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1227:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1421, + "mutability": "mutable", + "name": "requiredGasLimit", + "nameLocation": "1267:16:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1259:24:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1420, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1259:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1424, + "mutability": "mutable", + "name": "allowedRelayerAddresses", + "nameLocation": "1299:23:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1289:33:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + }, + "typeName": + { + "baseType": + { + "id": 1422, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1289:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 1423, + "nodeType": "ArrayTypeName", + "src": "1289:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1428, + "mutability": "mutable", + "name": "receipts", + "nameLocation": "1355:8:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1328:35:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + }, + "typeName": + { + "baseType": + { + "id": 1426, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1425, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "1328:24:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "1328:24:1" + }, + "referencedDeclaration": 1396, + "src": "1328:24:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 1427, + "nodeType": "ArrayTypeName", + "src": "1328:26:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1430, + "mutability": "mutable", + "name": "message", + "nameLocation": "1375:7:1", + "nodeType": "VariableDeclaration", + "scope": 1431, + "src": "1369:13:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1429, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1369:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "name": "TeleporterMessage", + "nameLocation": "1107:17:1", + "nodeType": "StructDefinition", + "scope": 1654, + "src": "1100:285:1", + "visibility": "public" + }, + { + "canonicalName": "TeleporterFeeInfo", + "id": 1436, + "members": + [ + { + "constant": false, + "id": 1433, + "mutability": "mutable", + "name": "feeTokenAddress", + "nameLocation": "1630:15:1", + "nodeType": "VariableDeclaration", + "scope": 1436, + "src": "1622:23:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1432, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1622:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1435, + "mutability": "mutable", + "name": "amount", + "nameLocation": "1659:6:1", + "nodeType": "VariableDeclaration", + "scope": 1436, + "src": "1651:14:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1434, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1651:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "name": "TeleporterFeeInfo", + "nameLocation": "1598:17:1", + "nodeType": "StructDefinition", + "scope": 1654, + "src": "1591:77:1", + "visibility": "public" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ITeleporterMessenger", + "contractDependencies": [], + "contractKind": "interface", + "documentation": + { + "id": 1437, + "nodeType": "StructuredDocumentation", + "src": "1670:216:1", + "text": " @dev Interface that describes functionalities for a cross-chain messenger implementing the Teleporter protcol.\n @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md" + }, + "fullyImplemented": false, + "id": 1653, + "linearizedBaseContracts": + [ + 1653 + ], + "name": "ITeleporterMessenger", + "nameLocation": "1897:20:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "anonymous": false, + "documentation": + { + "id": 1438, + "nodeType": "StructuredDocumentation", + "src": "1924:124:1", + "text": " @notice Emitted when the blockchain ID of the contract instance is initialized using the Warp precompile." + }, + "eventSelector": "1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104", + "id": 1442, + "name": "BlockchainIDInitialized", + "nameLocation": "2059:23:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1441, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1440, + "indexed": true, + "mutability": "mutable", + "name": "blockchainID", + "nameLocation": "2099:12:1", + "nodeType": "VariableDeclaration", + "scope": 1442, + "src": "2083:28:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1439, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2083:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "2082:30:1" + }, + "src": "2053:60:1" + }, + { + "anonymous": false, + "documentation": + { + "id": 1443, + "nodeType": "StructuredDocumentation", + "src": "2119:81:1", + "text": " @notice Emitted when sending a Teleporter message cross-chain." + }, + "eventSelector": "2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8", + "id": 1455, + "name": "SendCrossChainMessage", + "nameLocation": "2211:21:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1454, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1445, + "indexed": true, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "2258:9:1", + "nodeType": "VariableDeclaration", + "scope": 1455, + "src": "2242:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1444, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2242:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1447, + "indexed": true, + "mutability": "mutable", + "name": "destinationBlockchainID", + "nameLocation": "2293:23:1", + "nodeType": "VariableDeclaration", + "scope": 1455, + "src": "2277:39:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1446, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2277:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1450, + "indexed": false, + "mutability": "mutable", + "name": "message", + "nameLocation": "2344:7:1", + "nodeType": "VariableDeclaration", + "scope": 1455, + "src": "2326:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1449, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1448, + "name": "TeleporterMessage", + "nameLocations": + [ + "2326:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "2326:17:1" + }, + "referencedDeclaration": 1431, + "src": "2326:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1453, + "indexed": false, + "mutability": "mutable", + "name": "feeInfo", + "nameLocation": "2379:7:1", + "nodeType": "VariableDeclaration", + "scope": 1455, + "src": "2361:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 1452, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1451, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "2361:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "2361:17:1" + }, + "referencedDeclaration": 1436, + "src": "2361:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + } + ], + "src": "2232:160:1" + }, + "src": "2205:188:1" + }, + { + "anonymous": false, + "documentation": + { + "id": 1456, + "nodeType": "StructuredDocumentation", + "src": "2399:183:1", + "text": " @notice Emitted when an additional fee amount is added to a Teleporter message that had previously\n been sent, but not yet delivered to the destination chain." + }, + "eventSelector": "c1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e1", + "id": 1463, + "name": "AddFeeAmount", + "nameLocation": "2593:12:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1462, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1458, + "indexed": true, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "2622:9:1", + "nodeType": "VariableDeclaration", + "scope": 1463, + "src": "2606:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1457, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2606:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1461, + "indexed": false, + "mutability": "mutable", + "name": "updatedFeeInfo", + "nameLocation": "2651:14:1", + "nodeType": "VariableDeclaration", + "scope": 1463, + "src": "2633:32:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 1460, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1459, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "2633:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "2633:17:1" + }, + "referencedDeclaration": 1436, + "src": "2633:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + } + ], + "src": "2605:61:1" + }, + "src": "2587:80:1" + }, + { + "anonymous": false, + "documentation": + { + "id": 1464, + "nodeType": "StructuredDocumentation", + "src": "2673:220:1", + "text": " @notice Emitted when a Teleporter message is being delivered on the destination chain to an address,\n but message execution fails. Failed messages can then be retried with `retryMessageExecution`" + }, + "eventSelector": "4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c985", + "id": 1473, + "name": "MessageExecutionFailed", + "nameLocation": "2904:22:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1472, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1466, + "indexed": true, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "2952:9:1", + "nodeType": "VariableDeclaration", + "scope": 1473, + "src": "2936:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1465, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2936:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1468, + "indexed": true, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "2979:18:1", + "nodeType": "VariableDeclaration", + "scope": 1473, + "src": "2963:34:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1467, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2963:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1471, + "indexed": false, + "mutability": "mutable", + "name": "message", + "nameLocation": "3017:7:1", + "nodeType": "VariableDeclaration", + "scope": 1473, + "src": "2999:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1470, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1469, + "name": "TeleporterMessage", + "nameLocations": + [ + "2999:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "2999:17:1" + }, + "referencedDeclaration": 1431, + "src": "2999:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "2926:104:1" + }, + "src": "2898:133:1" + }, + { + "anonymous": false, + "documentation": + { + "id": 1474, + "nodeType": "StructuredDocumentation", + "src": "3037:325:1", + "text": " @notice Emitted when a Teleporter message is successfully executed with the\n specified destination address and message call data. This can occur either when\n the message is initially received, or on a retry attempt.\n Each message received can be executed successfully at most once." + }, + "eventSelector": "34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c", + "id": 1480, + "name": "MessageExecuted", + "nameLocation": "3373:15:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1479, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1476, + "indexed": true, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "3405:9:1", + "nodeType": "VariableDeclaration", + "scope": 1480, + "src": "3389:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1475, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3389:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1478, + "indexed": true, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "3432:18:1", + "nodeType": "VariableDeclaration", + "scope": 1480, + "src": "3416:34:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1477, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3416:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "3388:63:1" + }, + "src": "3367:85:1" + }, + { + "anonymous": false, + "documentation": + { + "id": 1481, + "nodeType": "StructuredDocumentation", + "src": "3458:85:1", + "text": " @notice Emitted when a TeleporterMessage is successfully received." + }, + "eventSelector": "292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e34", + "id": 1494, + "name": "ReceiveCrossChainMessage", + "nameLocation": "3554:24:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1493, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1483, + "indexed": true, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "3604:9:1", + "nodeType": "VariableDeclaration", + "scope": 1494, + "src": "3588:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1482, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3588:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1485, + "indexed": true, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "3639:18:1", + "nodeType": "VariableDeclaration", + "scope": 1494, + "src": "3623:34:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1484, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3623:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1487, + "indexed": true, + "mutability": "mutable", + "name": "deliverer", + "nameLocation": "3683:9:1", + "nodeType": "VariableDeclaration", + "scope": 1494, + "src": "3667:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1486, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3667:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1489, + "indexed": false, + "mutability": "mutable", + "name": "rewardRedeemer", + "nameLocation": "3710:14:1", + "nodeType": "VariableDeclaration", + "scope": 1494, + "src": "3702:22:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1488, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3702:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1492, + "indexed": false, + "mutability": "mutable", + "name": "message", + "nameLocation": "3752:7:1", + "nodeType": "VariableDeclaration", + "scope": 1494, + "src": "3734:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1491, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1490, + "name": "TeleporterMessage", + "nameLocations": + [ + "3734:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "3734:17:1" + }, + "referencedDeclaration": 1431, + "src": "3734:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "3578:187:1" + }, + "src": "3548:218:1" + }, + { + "anonymous": false, + "documentation": + { + "id": 1495, + "nodeType": "StructuredDocumentation", + "src": "3772:146:1", + "text": " @notice Emitted when a receipt is marked as received on the source chain that sent the\n corresponding Teleporter message." + }, + "eventSelector": "d13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf57", + "id": 1506, + "name": "ReceiptReceived", + "nameLocation": "3929:15:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1505, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1497, + "indexed": true, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "3970:9:1", + "nodeType": "VariableDeclaration", + "scope": 1506, + "src": "3954:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1496, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3954:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1499, + "indexed": true, + "mutability": "mutable", + "name": "destinationBlockchainID", + "nameLocation": "4005:23:1", + "nodeType": "VariableDeclaration", + "scope": 1506, + "src": "3989:39:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1498, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3989:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1501, + "indexed": true, + "mutability": "mutable", + "name": "relayerRewardAddress", + "nameLocation": "4054:20:1", + "nodeType": "VariableDeclaration", + "scope": 1506, + "src": "4038:36:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1500, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4038:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1504, + "indexed": false, + "mutability": "mutable", + "name": "feeInfo", + "nameLocation": "4102:7:1", + "nodeType": "VariableDeclaration", + "scope": 1506, + "src": "4084:25:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 1503, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1502, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "4084:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "4084:17:1" + }, + "referencedDeclaration": 1436, + "src": "4084:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + } + ], + "src": "3944:171:1" + }, + "src": "3923:193:1" + }, + { + "anonymous": false, + "documentation": + { + "id": 1507, + "nodeType": "StructuredDocumentation", + "src": "4122:87:1", + "text": " @notice Emitted when an account redeems accumulated relayer rewards." + }, + "eventSelector": "3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88", + "id": 1515, + "name": "RelayerRewardsRedeemed", + "nameLocation": "4220:22:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1514, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1509, + "indexed": true, + "mutability": "mutable", + "name": "redeemer", + "nameLocation": "4259:8:1", + "nodeType": "VariableDeclaration", + "scope": 1515, + "src": "4243:24:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1508, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4243:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1511, + "indexed": true, + "mutability": "mutable", + "name": "asset", + "nameLocation": "4285:5:1", + "nodeType": "VariableDeclaration", + "scope": 1515, + "src": "4269:21:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1510, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4269:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1513, + "indexed": false, + "mutability": "mutable", + "name": "amount", + "nameLocation": "4300:6:1", + "nodeType": "VariableDeclaration", + "scope": 1515, + "src": "4292:14:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1512, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4292:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4242:65:1" + }, + "src": "4214:94:1" + }, + { + "documentation": + { + "id": 1516, + "nodeType": "StructuredDocumentation", + "src": "4314:156:1", + "text": " @notice Called by transactions to initiate the sending of a cross-chain message.\n @return The message ID of the newly sent message." + }, + "functionSelector": "62448850", + "id": 1524, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "sendCrossChainMessage", + "nameLocation": "4484:21:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1520, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1519, + "mutability": "mutable", + "name": "messageInput", + "nameLocation": "4547:12:1", + "nodeType": "VariableDeclaration", + "scope": 1524, + "src": "4515:44:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_calldata_ptr", + "typeString": "struct TeleporterMessageInput" + }, + "typeName": + { + "id": 1518, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1517, + "name": "TeleporterMessageInput", + "nameLocations": + [ + "4515:22:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1411, + "src": "4515:22:1" + }, + "referencedDeclaration": 1411, + "src": "4515:22:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_storage_ptr", + "typeString": "struct TeleporterMessageInput" + } + }, + "visibility": "internal" + } + ], + "src": "4505:60:1" + }, + "returnParameters": + { + "id": 1523, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1522, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1524, + "src": "4584:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1521, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4584:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "4583:9:1" + }, + "scope": 1653, + "src": "4475:118:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1525, + "nodeType": "StructuredDocumentation", + "src": "4599:659:1", + "text": " @notice Called by transactions to retry the sending of a cross-chain message.\n @dev Retriggers the sending of a message previously emitted by sendCrossChainMessage that has not yet been acknowledged\n with a receipt from the destination chain. This may be necessary in the unlikely event that less than the required\n threshold of stake weight successfully inserted the message in their messages DB at the time of the first submission.\n The message is checked to have already been previously submitted by comparing its message hash against those kept in\n state until a receipt is received for the message." + }, + "functionSelector": "8245a1b0", + "id": 1531, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "retrySendCrossChainMessage", + "nameLocation": "5272:26:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1529, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1528, + "mutability": "mutable", + "name": "message", + "nameLocation": "5335:7:1", + "nodeType": "VariableDeclaration", + "scope": 1531, + "src": "5308:34:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1527, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1526, + "name": "TeleporterMessage", + "nameLocations": + [ + "5308:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "5308:17:1" + }, + "referencedDeclaration": 1431, + "src": "5308:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "5298:50:1" + }, + "returnParameters": + { + "id": 1530, + "nodeType": "ParameterList", + "parameters": [], + "src": "5357:0:1" + }, + "scope": 1653, + "src": "5263:95:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1532, + "nodeType": "StructuredDocumentation", + "src": "5364:415:1", + "text": " @notice Adds the additional fee amount to the amount to be paid to the relayer that delivers\n the given message ID to the destination chain.\n @dev The fee token address must be the same asset type as the fee asset specified in the original\n call to sendCrossChainMessage. Reverts if the message doesn't exist or there is already\n receipt of delivery of the message." + }, + "functionSelector": "8ac0fd04", + "id": 1541, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "addFeeAmount", + "nameLocation": "5793:12:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1539, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1534, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "5823:9:1", + "nodeType": "VariableDeclaration", + "scope": 1541, + "src": "5815:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1533, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5815:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1536, + "mutability": "mutable", + "name": "feeTokenAddress", + "nameLocation": "5850:15:1", + "nodeType": "VariableDeclaration", + "scope": 1541, + "src": "5842:23:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1535, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5842:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1538, + "mutability": "mutable", + "name": "additionalFeeAmount", + "nameLocation": "5883:19:1", + "nodeType": "VariableDeclaration", + "scope": 1541, + "src": "5875:27:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1537, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5875:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5805:103:1" + }, + "returnParameters": + { + "id": 1540, + "nodeType": "ParameterList", + "parameters": [], + "src": "5917:0:1" + }, + "scope": 1653, + "src": "5784:134:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1542, + "nodeType": "StructuredDocumentation", + "src": "5924:332:1", + "text": " @notice Receives a cross-chain message, and marks the `relayerRewardAddress` for fee reward for a successful delivery.\n @dev The message specified by `messageIndex` must be provided at that index in the access list storage slots of the transaction,\n and is verified in the precompile predicate." + }, + "functionSelector": "ccb5f809", + "id": 1549, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "receiveCrossChainMessage", + "nameLocation": "6270:24:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1547, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1544, + "mutability": "mutable", + "name": "messageIndex", + "nameLocation": "6302:12:1", + "nodeType": "VariableDeclaration", + "scope": 1549, + "src": "6295:19:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": + { + "id": 1543, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "6295:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1546, + "mutability": "mutable", + "name": "relayerRewardAddress", + "nameLocation": "6324:20:1", + "nodeType": "VariableDeclaration", + "scope": 1549, + "src": "6316:28:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1545, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6316:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "6294:51:1" + }, + "returnParameters": + { + "id": 1548, + "nodeType": "ParameterList", + "parameters": [], + "src": "6354:0:1" + }, + "scope": 1653, + "src": "6261:94:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1550, + "nodeType": "StructuredDocumentation", + "src": "6361:637:1", + "text": " @notice Retries the execution of a previously delivered message by verifying the payload matches\n the hash of the payload originally delivered, and calling the destination address again.\n @dev Intended to be used if message excution failed on initial delivery of the Teleporter message.\n For example, this may occur if the original required gas limit was not sufficient for the message\n execution, or if the destination address did not contain a contract, but a compatible contract\n was later deployed to that address. Messages are ensured to be successfully executed at most once." + }, + "functionSelector": "fc2d6197", + "id": 1558, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "retryMessageExecution", + "nameLocation": "7012:21:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1556, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1552, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "7051:18:1", + "nodeType": "VariableDeclaration", + "scope": 1558, + "src": "7043:26:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1551, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7043:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1555, + "mutability": "mutable", + "name": "message", + "nameLocation": "7106:7:1", + "nodeType": "VariableDeclaration", + "scope": 1558, + "src": "7079:34:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1554, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1553, + "name": "TeleporterMessage", + "nameLocations": + [ + "7079:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "7079:17:1" + }, + "referencedDeclaration": 1431, + "src": "7079:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "7033:86:1" + }, + "returnParameters": + { + "id": 1557, + "nodeType": "ParameterList", + "parameters": [], + "src": "7128:0:1" + }, + "scope": 1653, + "src": "7003:126:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1559, + "nodeType": "StructuredDocumentation", + "src": "7135:399:1", + "text": " @notice Sends the receipts for the given `messageIDs`.\n @dev Sends the specified message receipts in a new message (with an empty payload) back to the source chain.\n This is intended for use in sending receipts that have not been sent in a timely manner by the standard\n receipt delivery mechanism.\n @return The message ID of the newly sent message." + }, + "functionSelector": "a9a85614", + "id": 1575, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "sendSpecifiedReceipts", + "nameLocation": "7548:21:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1571, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1561, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "7587:18:1", + "nodeType": "VariableDeclaration", + "scope": 1575, + "src": "7579:26:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1560, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7579:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1564, + "mutability": "mutable", + "name": "messageIDs", + "nameLocation": "7634:10:1", + "nodeType": "VariableDeclaration", + "scope": 1575, + "src": "7615:29:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_calldata_ptr", + "typeString": "bytes32[]" + }, + "typeName": + { + "baseType": + { + "id": 1562, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7615:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1563, + "nodeType": "ArrayTypeName", + "src": "7615:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1567, + "mutability": "mutable", + "name": "feeInfo", + "nameLocation": "7681:7:1", + "nodeType": "VariableDeclaration", + "scope": 1575, + "src": "7654:34:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_calldata_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 1566, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1565, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "7654:17:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "7654:17:1" + }, + "referencedDeclaration": 1436, + "src": "7654:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1570, + "mutability": "mutable", + "name": "allowedRelayerAddresses", + "nameLocation": "7717:23:1", + "nodeType": "VariableDeclaration", + "scope": 1575, + "src": "7698:42:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_calldata_ptr", + "typeString": "address[]" + }, + "typeName": + { + "baseType": + { + "id": 1568, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "7698:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 1569, + "nodeType": "ArrayTypeName", + "src": "7698:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + } + ], + "src": "7569:177:1" + }, + "returnParameters": + { + "id": 1574, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1573, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1575, + "src": "7765:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1572, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7765:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "7764:9:1" + }, + "scope": 1653, + "src": "7539:235:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1576, + "nodeType": "StructuredDocumentation", + "src": "7780:98:1", + "text": " @notice Sends any fee amount rewards for the given fee asset out to the caller." + }, + "functionSelector": "22296c3a", + "id": 1581, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "redeemRelayerRewards", + "nameLocation": "7892:20:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1579, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1578, + "mutability": "mutable", + "name": "feeTokenAddress", + "nameLocation": "7930:15:1", + "nodeType": "VariableDeclaration", + "scope": 1581, + "src": "7922:23:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1577, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "7922:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "7912:39:1" + }, + "returnParameters": + { + "id": 1580, + "nodeType": "ParameterList", + "parameters": [], + "src": "7960:0:1" + }, + "scope": 1653, + "src": "7883:78:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1582, + "nodeType": "StructuredDocumentation", + "src": "7967:139:1", + "text": " @notice Gets the hash of a given message stored in the EVM state, if the message exists.\n @return The message hash" + }, + "functionSelector": "399b77da", + "id": 1589, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getMessageHash", + "nameLocation": "8120:14:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1585, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1584, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "8152:9:1", + "nodeType": "VariableDeclaration", + "scope": 1589, + "src": "8144:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1583, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8144:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "8134:33:1" + }, + "returnParameters": + { + "id": 1588, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1587, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1589, + "src": "8191:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1586, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8191:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "8190:9:1" + }, + "scope": 1653, + "src": "8111:89:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1590, + "nodeType": "StructuredDocumentation", + "src": "8206:175:1", + "text": " @notice Checks whether or not the given message has been received by this chain.\n @return Boolean representing if the given message has been received." + }, + "functionSelector": "ebc3b1ba", + "id": 1597, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "messageReceived", + "nameLocation": "8395:15:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1593, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1592, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "8428:9:1", + "nodeType": "VariableDeclaration", + "scope": 1597, + "src": "8420:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1591, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8420:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "8410:33:1" + }, + "returnParameters": + { + "id": 1596, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1595, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1597, + "src": "8467:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 1594, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "8467:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "8466:6:1" + }, + "scope": 1653, + "src": "8386:87:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1598, + "nodeType": "StructuredDocumentation", + "src": "8479:250:1", + "text": " @notice Returns the address the relayer reward should be sent to on the source chain\n for a given message, assuming that the message has already been delivered.\n @return The relayer reward address for the given message." + }, + "functionSelector": "2e27c223", + "id": 1605, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getRelayerRewardAddress", + "nameLocation": "8743:23:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1601, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1600, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "8784:9:1", + "nodeType": "VariableDeclaration", + "scope": 1605, + "src": "8776:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1599, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8776:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "8766:33:1" + }, + "returnParameters": + { + "id": 1604, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1603, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1605, + "src": "8823:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1602, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8823:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "8822:9:1" + }, + "scope": 1653, + "src": "8734:98:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1606, + "nodeType": "StructuredDocumentation", + "src": "8838:199:1", + "text": " @notice Gets the current reward amount of a given fee asset that is redeemable by the given relayer.\n @return The amount of the fee asset redeemable by the specified relayer." + }, + "functionSelector": "c473eef8", + "id": 1615, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "checkRelayerRewardAmount", + "nameLocation": "9051:24:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1611, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1608, + "mutability": "mutable", + "name": "relayer", + "nameLocation": "9093:7:1", + "nodeType": "VariableDeclaration", + "scope": 1615, + "src": "9085:15:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1607, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9085:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1610, + "mutability": "mutable", + "name": "feeTokenAddress", + "nameLocation": "9118:15:1", + "nodeType": "VariableDeclaration", + "scope": 1615, + "src": "9110:23:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1609, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9110:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "9075:64:1" + }, + "returnParameters": + { + "id": 1614, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1613, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1615, + "src": "9163:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1612, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9163:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "9162:9:1" + }, + "scope": 1653, + "src": "9042:130:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1616, + "nodeType": "StructuredDocumentation", + "src": "9178:259:1", + "text": " @notice Gets the fee token address and amount for a given sent message.\n @return The fee token address and fee amount for a the given sent message ID.\n If the message ID is not found, zero address and amount values are returned." + }, + "functionSelector": "e69d606a", + "id": 1625, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getFeeInfo", + "nameLocation": "9451:10:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1619, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1618, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "9479:9:1", + "nodeType": "VariableDeclaration", + "scope": 1625, + "src": "9471:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1617, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9471:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "9461:33:1" + }, + "returnParameters": + { + "id": 1624, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1621, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1625, + "src": "9518:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1620, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9518:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1623, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1625, + "src": "9527:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1622, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9527:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "9517:18:1" + }, + "scope": 1653, + "src": "9442:94:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1626, + "nodeType": "StructuredDocumentation", + "src": "9542:506:1", + "text": " @notice Gets the message ID that would currently be used for the next message sent from the contract\n instance to the given destination blockchain.\n @dev This message ID may never be used in the event that the next call to sendCrossChainMessage in a\n transaction uses a different destination blockchain. The current value as returned by this function will\n change with each successful call to sendCrossChainMessage.\n @return The specified message ID." + }, + "functionSelector": "df20e8bc", + "id": 1633, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getNextMessageID", + "nameLocation": "10062:16:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1629, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1628, + "mutability": "mutable", + "name": "destinationBlockchainID", + "nameLocation": "10096:23:1", + "nodeType": "VariableDeclaration", + "scope": 1633, + "src": "10088:31:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1627, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10088:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "10078:47:1" + }, + "returnParameters": + { + "id": 1632, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1631, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1633, + "src": "10149:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1630, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10149:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "10148:9:1" + }, + "scope": 1653, + "src": "10053:105:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1634, + "nodeType": "StructuredDocumentation", + "src": "10164:152:1", + "text": " @notice Gets the number of receipts that are waiting to be sent to the given source chain ID.\n @return Size of the given queue." + }, + "functionSelector": "2bc8b0bf", + "id": 1641, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getReceiptQueueSize", + "nameLocation": "10330:19:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1637, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1636, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "10367:18:1", + "nodeType": "VariableDeclaration", + "scope": 1641, + "src": "10359:26:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1635, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10359:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "10349:42:1" + }, + "returnParameters": + { + "id": 1640, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1639, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1641, + "src": "10415:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1638, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10415:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "10414:9:1" + }, + "scope": 1653, + "src": "10321:103:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 1642, + "nodeType": "StructuredDocumentation", + "src": "10430:144:1", + "text": " @notice Gets the receipt at the given index in the queue for the given source chain ID.\n @return The receipt requested." + }, + "functionSelector": "892bf412", + "id": 1652, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "getReceiptAtIndex", + "nameLocation": "10588:17:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1647, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1644, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "10623:18:1", + "nodeType": "VariableDeclaration", + "scope": 1652, + "src": "10615:26:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1643, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10615:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1646, + "mutability": "mutable", + "name": "index", + "nameLocation": "10659:5:1", + "nodeType": "VariableDeclaration", + "scope": 1652, + "src": "10651:13:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1645, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10651:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "10605:65:1" + }, + "returnParameters": + { + "id": 1651, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1650, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1652, + "src": "10694:31:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt" + }, + "typeName": + { + "id": 1649, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1648, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "10694:24:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "10694:24:1" + }, + "referencedDeclaration": 1396, + "src": "10694:24:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "visibility": "internal" + } + ], + "src": "10693:33:1" + }, + "scope": 1653, + "src": "10579:148:1", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + } + ], + "scope": 1654, + "src": "1887:8842:1", + "usedErrors": [], + "usedEvents": + [ + 1442, + 1455, + 1463, + 1473, + 1480, + 1494, + 1506, + 1515 + ] + } + ], + "src": "145:10585:1" + }, + "id": 1 + }, + "icm-contracts/contracts/teleporter/ITeleporterReceiver.sol": + { + "AST": + { + "absolutePath": "icm-contracts/contracts/teleporter/ITeleporterReceiver.sol", + "exportedSymbols": + { + "ITeleporterReceiver": + [ + 1667 + ] + }, + "id": 1668, + "license": "LicenseRef-Ecosystem", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1655, + "literals": + [ + "solidity", + "0.8", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "150:23:2" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ITeleporterReceiver", + "contractDependencies": [], + "contractKind": "interface", + "documentation": + { + "id": 1656, + "nodeType": "StructuredDocumentation", + "src": "175:202:2", + "text": " @dev Interface that cross-chain applications must implement to receive messages from Teleporter.\n @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md" + }, + "fullyImplemented": false, + "id": 1667, + "linearizedBaseContracts": + [ + 1667 + ], + "name": "ITeleporterReceiver", + "nameLocation": "388:19:2", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "documentation": + { + "id": 1657, + "nodeType": "StructuredDocumentation", + "src": "414:323:2", + "text": " @dev Called by TeleporterMessenger on the receiving chain.\n @param sourceBlockchainID is provided by the TeleporterMessenger contract.\n @param originSenderAddress is provided by the TeleporterMessenger contract.\n @param message is the TeleporterMessage payload set by the sender." + }, + "functionSelector": "c868efaa", + "id": 1666, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "receiveTeleporterMessage", + "nameLocation": "751:24:2", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1664, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1659, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "793:18:2", + "nodeType": "VariableDeclaration", + "scope": 1666, + "src": "785:26:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1658, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "785:7:2", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1661, + "mutability": "mutable", + "name": "originSenderAddress", + "nameLocation": "829:19:2", + "nodeType": "VariableDeclaration", + "scope": 1666, + "src": "821:27:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1660, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "821:7:2", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1663, + "mutability": "mutable", + "name": "message", + "nameLocation": "873:7:2", + "nodeType": "VariableDeclaration", + "scope": 1666, + "src": "858:22:2", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1662, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "858:5:2", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "775:111:2" + }, + "returnParameters": + { + "id": 1665, + "nodeType": "ParameterList", + "parameters": [], + "src": "895:0:2" + }, + "scope": 1667, + "src": "742:154:2", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 1668, + "src": "378:520:2", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "150:749:2" + }, + "id": 2 + }, + "icm-contracts/contracts/teleporter/ReceiptQueue.sol": + { + "AST": + { + "absolutePath": "icm-contracts/contracts/teleporter/ReceiptQueue.sol", + "exportedSymbols": + { + "Math": + [ + 3443 + ], + "ReceiptQueue": + [ + 1870 + ], + "TeleporterMessageReceipt": + [ + 1396 + ] + }, + "id": 1871, + "license": "LicenseRef-Ecosystem", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1669, + "literals": + [ + "solidity", + "0.8", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "145:23:3" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol", + "file": "@openzeppelin/contracts@5.0.2/utils/math/Math.sol", + "id": 1671, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1871, + "sourceUnit": 3444, + "src": "170:71:3", + "symbolAliases": + [ + { + "foreign": + { + "id": 1670, + "name": "Math", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3443, + "src": "178:4:3", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/contracts/teleporter/ITeleporterMessenger.sol", + "file": "./ITeleporterMessenger.sol", + "id": 1673, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1871, + "sourceUnit": 1654, + "src": "242:68:3", + "symbolAliases": + [ + { + "foreign": + { + "id": 1672, + "name": "TeleporterMessageReceipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1396, + "src": "250:24:3", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ReceiptQueue", + "contractDependencies": [], + "contractKind": "library", + "documentation": + { + "id": 1674, + "nodeType": "StructuredDocumentation", + "src": "312:356:3", + "text": " @dev ReceiptQueue is a convenience library that creates a queue-like interface of\n TeleporterMessageReceipt structs. It provides FIFO properties.\n Note: All functions in this library are internal so that the library is not deployed as a contract.\n @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md" + }, + "fullyImplemented": true, + "id": 1870, + "linearizedBaseContracts": + [ + 1870 + ], + "name": "ReceiptQueue", + "nameLocation": "677:12:3", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "canonicalName": "ReceiptQueue.TeleporterMessageReceiptQueue", + "id": 1684, + "members": + [ + { + "constant": false, + "id": 1676, + "mutability": "mutable", + "name": "first", + "nameLocation": "877:5:3", + "nodeType": "VariableDeclaration", + "scope": 1684, + "src": "869:13:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1675, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "869:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1678, + "mutability": "mutable", + "name": "last", + "nameLocation": "967:4:3", + "nodeType": "VariableDeclaration", + "scope": 1684, + "src": "959:12:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1677, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "959:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1683, + "mutability": "mutable", + "name": "data", + "nameLocation": "1181:4:3", + "nodeType": "VariableDeclaration", + "scope": 1684, + "src": "1122:63:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_TeleporterMessageReceipt_$1396_storage_$", + "typeString": "mapping(uint256 => struct TeleporterMessageReceipt)" + }, + "typeName": + { + "id": 1682, + "keyName": "index", + "keyNameLocation": "1138:5:3", + "keyType": + { + "id": 1679, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1130:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Mapping", + "src": "1122:58:3", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_TeleporterMessageReceipt_$1396_storage_$", + "typeString": "mapping(uint256 => struct TeleporterMessageReceipt)" + }, + "valueName": "receipt", + "valueNameLocation": "1172:7:3", + "valueType": + { + "id": 1681, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1680, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "1147:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "1147:24:3" + }, + "referencedDeclaration": 1396, + "src": "1147:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + } + }, + "visibility": "internal" + } + ], + "name": "TeleporterMessageReceiptQueue", + "nameLocation": "762:29:3", + "nodeType": "StructDefinition", + "scope": 1870, + "src": "755:437:3", + "visibility": "public" + }, + { + "constant": true, + "id": 1687, + "mutability": "constant", + "name": "_MAXIMUM_RECEIPT_COUNT", + "nameLocation": "1293:22:3", + "nodeType": "VariableDeclaration", + "scope": 1870, + "src": "1268:51:3", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1685, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1268:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "hexValue": "35", + "id": 1686, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1318:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + }, + "value": "5" + }, + "visibility": "private" + }, + { + "body": + { + "id": 1707, + "nodeType": "Block", + "src": "1572:51:3", + "statements": + [ + { + "expression": + { + "id": 1705, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "expression": + { + "id": 1697, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1691, + "src": "1582:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1702, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1588:4:3", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 1683, + "src": "1582:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_TeleporterMessageReceipt_$1396_storage_$", + "typeString": "mapping(uint256 => struct TeleporterMessageReceipt storage ref)" + } + }, + "id": 1703, + "indexExpression": + { + "id": 1701, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "1593:12:3", + "subExpression": + { + "expression": + { + "id": 1699, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1691, + "src": "1593:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1700, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberLocation": "1599:4:3", + "memberName": "last", + "nodeType": "MemberAccess", + "referencedDeclaration": 1678, + "src": "1593:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "1582:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage", + "typeString": "struct TeleporterMessageReceipt storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1704, + "name": "receipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1694, + "src": "1609:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "src": "1582:34:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage", + "typeString": "struct TeleporterMessageReceipt storage ref" + } + }, + "id": 1706, + "nodeType": "ExpressionStatement", + "src": "1582:34:3" + } + ] + }, + "documentation": + { + "id": 1688, + "nodeType": "StructuredDocumentation", + "src": "1381:52:3", + "text": " @dev Adds a receipt to the queue." + }, + "id": 1708, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "enqueue", + "nameLocation": "1447:7:3", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1695, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1691, + "mutability": "mutable", + "name": "queue", + "nameLocation": "1502:5:3", + "nodeType": "VariableDeclaration", + "scope": 1708, + "src": "1464:43:3", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + }, + "typeName": + { + "id": 1690, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1689, + "name": "TeleporterMessageReceiptQueue", + "nameLocations": + [ + "1464:29:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1684, + "src": "1464:29:3" + }, + "referencedDeclaration": 1684, + "src": "1464:29:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1694, + "mutability": "mutable", + "name": "receipt", + "nameLocation": "1549:7:3", + "nodeType": "VariableDeclaration", + "scope": 1708, + "src": "1517:39:3", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt" + }, + "typeName": + { + "id": 1693, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1692, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "1517:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "1517:24:3" + }, + "referencedDeclaration": 1396, + "src": "1517:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "visibility": "internal" + } + ], + "src": "1454:108:3" + }, + "returnParameters": + { + "id": 1696, + "nodeType": "ParameterList", + "parameters": [], + "src": "1572:0:3" + }, + "scope": 1870, + "src": "1438:185:3", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 1755, + "nodeType": "Block", + "src": "1905:276:3", + "statements": + [ + { + "assignments": + [ + 1719 + ], + "declarations": + [ + { + "constant": false, + "id": 1719, + "mutability": "mutable", + "name": "first_", + "nameLocation": "1923:6:3", + "nodeType": "VariableDeclaration", + "scope": 1755, + "src": "1915:14:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1718, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1915:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1722, + "initialValue": + { + "expression": + { + "id": 1720, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1712, + "src": "1932:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1721, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1938:5:3", + "memberName": "first", + "nodeType": "MemberAccess", + "referencedDeclaration": 1676, + "src": "1932:11:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1915:28:3" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1727, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 1724, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1712, + "src": "1961:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1725, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1967:4:3", + "memberName": "last", + "nodeType": "MemberAccess", + "referencedDeclaration": 1678, + "src": "1961:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "id": 1726, + "name": "first_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1719, + "src": "1975:6:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1961:20:3", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5265636569707451756575653a20656d707479207175657565", + "id": 1728, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1983:27:3", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_c1c69488e684003556607f357e56aa4e2cad0743a01d475de0ebbe588b0ddd42", + "typeString": "literal_string \"ReceiptQueue: empty queue\"" + }, + "value": "ReceiptQueue: empty queue" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c1c69488e684003556607f357e56aa4e2cad0743a01d475de0ebbe588b0ddd42", + "typeString": "literal_string \"ReceiptQueue: empty queue\"" + } + ], + "id": 1723, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "1953:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1729, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1953:58:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1730, + "nodeType": "ExpressionStatement", + "src": "1953:58:3" + }, + { + "assignments": + [ + 1733 + ], + "declarations": + [ + { + "constant": false, + "id": 1733, + "mutability": "mutable", + "name": "receipt", + "nameLocation": "2053:7:3", + "nodeType": "VariableDeclaration", + "scope": 1755, + "src": "2021:39:3", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt" + }, + "typeName": + { + "id": 1732, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1731, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "2021:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "2021:24:3" + }, + "referencedDeclaration": 1396, + "src": "2021:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "visibility": "internal" + } + ], + "id": 1738, + "initialValue": + { + "baseExpression": + { + "expression": + { + "id": 1734, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1712, + "src": "2063:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1735, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2069:4:3", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 1683, + "src": "2063:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_TeleporterMessageReceipt_$1396_storage_$", + "typeString": "mapping(uint256 => struct TeleporterMessageReceipt storage ref)" + } + }, + "id": 1737, + "indexExpression": + { + "id": 1736, + "name": "first_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1719, + "src": "2074:6:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "2063:18:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage", + "typeString": "struct TeleporterMessageReceipt storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2021:60:3" + }, + { + "expression": + { + "id": 1743, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "2091:25:3", + "subExpression": + { + "baseExpression": + { + "expression": + { + "id": 1739, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1712, + "src": "2098:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1740, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2104:4:3", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 1683, + "src": "2098:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_TeleporterMessageReceipt_$1396_storage_$", + "typeString": "mapping(uint256 => struct TeleporterMessageReceipt storage ref)" + } + }, + "id": 1742, + "indexExpression": + { + "id": 1741, + "name": "first_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1719, + "src": "2109:6:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "2098:18:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage", + "typeString": "struct TeleporterMessageReceipt storage ref" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1744, + "nodeType": "ExpressionStatement", + "src": "2091:25:3" + }, + { + "expression": + { + "id": 1751, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "expression": + { + "id": 1745, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1712, + "src": "2126:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1747, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberLocation": "2132:5:3", + "memberName": "first", + "nodeType": "MemberAccess", + "referencedDeclaration": 1676, + "src": "2126:11:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1750, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 1748, + "name": "first_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1719, + "src": "2140:6:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "hexValue": "31", + "id": 1749, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2149:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "2140:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2126:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1752, + "nodeType": "ExpressionStatement", + "src": "2126:24:3" + }, + { + "expression": + { + "id": 1753, + "name": "receipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1733, + "src": "2167:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "functionReturnParameters": 1717, + "id": 1754, + "nodeType": "Return", + "src": "2160:14:3" + } + ] + }, + "documentation": + { + "id": 1709, + "nodeType": "StructuredDocumentation", + "src": "1629:144:3", + "text": " @dev Removes the oldest outstanding receipt from the queue.\n Requirements:\n - The queue must be non-empty." + }, + "id": 1756, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "dequeue", + "nameLocation": "1787:7:3", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1713, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1712, + "mutability": "mutable", + "name": "queue", + "nameLocation": "1842:5:3", + "nodeType": "VariableDeclaration", + "scope": 1756, + "src": "1804:43:3", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + }, + "typeName": + { + "id": 1711, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1710, + "name": "TeleporterMessageReceiptQueue", + "nameLocations": + [ + "1804:29:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1684, + "src": "1804:29:3" + }, + "referencedDeclaration": 1684, + "src": "1804:29:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + } + }, + "visibility": "internal" + } + ], + "src": "1794:59:3" + }, + "returnParameters": + { + "id": 1717, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1716, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1756, + "src": "1872:31:3", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt" + }, + "typeName": + { + "id": 1715, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1714, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "1872:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "1872:24:3" + }, + "referencedDeclaration": 1396, + "src": "1872:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "visibility": "internal" + } + ], + "src": "1871:33:3" + }, + "scope": 1870, + "src": "1778:403:3", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 1822, + "nodeType": "Block", + "src": "2471:502:3", + "statements": + [ + { + "assignments": + [ + 1768 + ], + "declarations": + [ + { + "constant": false, + "id": 1768, + "mutability": "mutable", + "name": "resultSize", + "nameLocation": "2591:10:3", + "nodeType": "VariableDeclaration", + "scope": 1822, + "src": "2583:18:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1767, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2583:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1776, + "initialValue": + { + "arguments": + [ + { + "id": 1771, + "name": "_MAXIMUM_RECEIPT_COUNT", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1687, + "src": "2613:22:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": + [ + { + "id": 1773, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1760, + "src": "2642:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + ], + "id": 1772, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1839, + "src": "2637:4:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$returns$_t_uint256_$", + "typeString": "function (struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer) view returns (uint256)" + } + }, + "id": 1774, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2637:11:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": + { + "id": 1769, + "name": "Math", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3443, + "src": "2604:4:3", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_Math_$3443_$", + "typeString": "type(library Math)" + } + }, + "id": 1770, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2609:3:3", + "memberName": "min", + "nodeType": "MemberAccess", + "referencedDeclaration": 2594, + "src": "2604:8:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 1775, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2604:45:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2583:66:3" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1779, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 1777, + "name": "resultSize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1768, + "src": "2663:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 1778, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2677:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "2663:15:3", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1788, + "nodeType": "IfStatement", + "src": "2659:86:3", + "trueBody": + { + "id": 1787, + "nodeType": "Block", + "src": "2680:65:3", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 1784, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2732:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1783, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "2701:30:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr_$", + "typeString": "function (uint256) pure returns (struct TeleporterMessageReceipt memory[] memory)" + }, + "typeName": + { + "baseType": + { + "id": 1781, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1780, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "2705:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "2705:24:3" + }, + "referencedDeclaration": 1396, + "src": "2705:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 1782, + "nodeType": "ArrayTypeName", + "src": "2705:26:3", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + } + }, + "id": 1785, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2701:33:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "functionReturnParameters": 1766, + "id": 1786, + "nodeType": "Return", + "src": "2694:40:3" + } + ] + } + }, + { + "assignments": + [ + 1793 + ], + "declarations": + [ + { + "constant": false, + "id": 1793, + "mutability": "mutable", + "name": "receipts", + "nameLocation": "2789:8:3", + "nodeType": "VariableDeclaration", + "scope": 1822, + "src": "2755:42:3", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + }, + "typeName": + { + "baseType": + { + "id": 1791, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1790, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "2755:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "2755:24:3" + }, + "referencedDeclaration": 1396, + "src": "2755:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 1792, + "nodeType": "ArrayTypeName", + "src": "2755:26:3", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + }, + "visibility": "internal" + } + ], + "id": 1800, + "initialValue": + { + "arguments": + [ + { + "id": 1798, + "name": "resultSize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1768, + "src": "2831:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1797, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "2800:30:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr_$", + "typeString": "function (uint256) pure returns (struct TeleporterMessageReceipt memory[] memory)" + }, + "typeName": + { + "baseType": + { + "id": 1795, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1794, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "2804:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "2804:24:3" + }, + "referencedDeclaration": 1396, + "src": "2804:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 1796, + "nodeType": "ArrayTypeName", + "src": "2804:26:3", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + } + }, + "id": 1799, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2800:42:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2755:87:3" + }, + { + "body": + { + "id": 1818, + "nodeType": "Block", + "src": "2889:53:3", + "statements": + [ + { + "expression": + { + "id": 1816, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "id": 1810, + "name": "receipts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1793, + "src": "2903:8:3", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "id": 1812, + "indexExpression": + { + "id": 1811, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1802, + "src": "2912:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "2903:11:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "arguments": + [ + { + "id": 1814, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1760, + "src": "2925:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + ], + "id": 1813, + "name": "dequeue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1756, + "src": "2917:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$returns$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$", + "typeString": "function (struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer) returns (struct TeleporterMessageReceipt memory)" + } + }, + "id": 1815, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2917:14:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "src": "2903:28:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "id": 1817, + "nodeType": "ExpressionStatement", + "src": "2903:28:3" + } + ] + }, + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1806, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 1804, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1802, + "src": "2868:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 1805, + "name": "resultSize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1768, + "src": "2872:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2868:14:3", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1819, + "initializationExpression": + { + "assignments": + [ + 1802 + ], + "declarations": + [ + { + "constant": false, + "id": 1802, + "mutability": "mutable", + "name": "i", + "nameLocation": "2865:1:3", + "nodeType": "VariableDeclaration", + "scope": 1819, + "src": "2857:9:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1801, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2857:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1803, + "nodeType": "VariableDeclarationStatement", + "src": "2857:9:3" + }, + "isSimpleCounterLoop": true, + "loopExpression": + { + "expression": + { + "id": 1808, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": true, + "src": "2884:3:3", + "subExpression": + { + "id": 1807, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1802, + "src": "2886:1:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1809, + "nodeType": "ExpressionStatement", + "src": "2884:3:3" + }, + "nodeType": "ForStatement", + "src": "2852:90:3" + }, + { + "expression": + { + "id": 1820, + "name": "receipts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1793, + "src": "2958:8:3", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "functionReturnParameters": 1766, + "id": 1821, + "nodeType": "Return", + "src": "2951:15:3" + } + ] + }, + "documentation": + { + "id": 1757, + "nodeType": "StructuredDocumentation", + "src": "2187:129:3", + "text": " @dev Returns the outstanding receipts for the given chain ID that should be included in the next message sent." + }, + "id": 1823, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getOutstandingReceiptsToSend", + "nameLocation": "2330:28:3", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1761, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1760, + "mutability": "mutable", + "name": "queue", + "nameLocation": "2406:5:3", + "nodeType": "VariableDeclaration", + "scope": 1823, + "src": "2368:43:3", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + }, + "typeName": + { + "id": 1759, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1758, + "name": "TeleporterMessageReceiptQueue", + "nameLocations": + [ + "2368:29:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1684, + "src": "2368:29:3" + }, + "referencedDeclaration": 1684, + "src": "2368:29:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + } + }, + "visibility": "internal" + } + ], + "src": "2358:59:3" + }, + "returnParameters": + { + "id": 1766, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1765, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1823, + "src": "2436:33:3", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + }, + "typeName": + { + "baseType": + { + "id": 1763, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1762, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "2436:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "2436:24:3" + }, + "referencedDeclaration": 1396, + "src": "2436:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 1764, + "nodeType": "ArrayTypeName", + "src": "2436:26:3", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + }, + "visibility": "internal" + } + ], + "src": "2435:35:3" + }, + "scope": 1870, + "src": "2321:652:3", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 1838, + "nodeType": "Block", + "src": "3169:48:3", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1836, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 1832, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1827, + "src": "3186:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1833, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3192:4:3", + "memberName": "last", + "nodeType": "MemberAccess", + "referencedDeclaration": 1678, + "src": "3186:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "expression": + { + "id": 1834, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1827, + "src": "3199:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1835, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3205:5:3", + "memberName": "first", + "nodeType": "MemberAccess", + "referencedDeclaration": 1676, + "src": "3199:11:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3186:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 1831, + "id": 1837, + "nodeType": "Return", + "src": "3179:31:3" + } + ] + }, + "documentation": + { + "id": 1824, + "nodeType": "StructuredDocumentation", + "src": "2979:80:3", + "text": " @dev Returns the number of outstanding receipts in the queue." + }, + "id": 1839, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "size", + "nameLocation": "3073:4:3", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1828, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1827, + "mutability": "mutable", + "name": "queue", + "nameLocation": "3125:5:3", + "nodeType": "VariableDeclaration", + "scope": 1839, + "src": "3087:43:3", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + }, + "typeName": + { + "id": 1826, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1825, + "name": "TeleporterMessageReceiptQueue", + "nameLocations": + [ + "3087:29:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1684, + "src": "3087:29:3" + }, + "referencedDeclaration": 1684, + "src": "3087:29:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + } + }, + "visibility": "internal" + } + ], + "src": "3077:59:3" + }, + "returnParameters": + { + "id": 1831, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1830, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1839, + "src": "3160:7:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1829, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3160:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3159:9:3" + }, + "scope": 1870, + "src": "3064:153:3", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 1868, + "nodeType": "Block", + "src": "3469:130:3", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1856, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 1852, + "name": "index", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1845, + "src": "3487:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "arguments": + [ + { + "id": 1854, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1843, + "src": "3500:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + ], + "id": 1853, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1839, + "src": "3495:4:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$returns$_t_uint256_$", + "typeString": "function (struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer) view returns (uint256)" + } + }, + "id": 1855, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3495:11:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3487:19:3", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5265636569707451756575653a20696e646578206f7574206f6620626f756e6473", + "id": 1857, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3508:35:3", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_44090384bfab92e482129469534d7a3feb7fd09dba706d4266db48e0b3529b19", + "typeString": "literal_string \"ReceiptQueue: index out of bounds\"" + }, + "value": "ReceiptQueue: index out of bounds" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_44090384bfab92e482129469534d7a3feb7fd09dba706d4266db48e0b3529b19", + "typeString": "literal_string \"ReceiptQueue: index out of bounds\"" + } + ], + "id": 1851, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "3479:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1858, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3479:65:3", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1859, + "nodeType": "ExpressionStatement", + "src": "3479:65:3" + }, + { + "expression": + { + "baseExpression": + { + "expression": + { + "id": 1860, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1843, + "src": "3561:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1861, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3567:4:3", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 1683, + "src": "3561:10:3", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_uint256_$_t_struct$_TeleporterMessageReceipt_$1396_storage_$", + "typeString": "mapping(uint256 => struct TeleporterMessageReceipt storage ref)" + } + }, + "id": 1866, + "indexExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1865, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 1862, + "name": "queue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1843, + "src": "3572:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer" + } + }, + "id": 1863, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3578:5:3", + "memberName": "first", + "nodeType": "MemberAccess", + "referencedDeclaration": 1676, + "src": "3572:11:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "id": 1864, + "name": "index", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1845, + "src": "3586:5:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3572:19:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3561:31:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage", + "typeString": "struct TeleporterMessageReceipt storage ref" + } + }, + "functionReturnParameters": 1850, + "id": 1867, + "nodeType": "Return", + "src": "3554:38:3" + } + ] + }, + "documentation": + { + "id": 1840, + "nodeType": "StructuredDocumentation", + "src": "3223:76:3", + "text": " @dev Returns the receipt at the given index in the queue." + }, + "id": 1869, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getReceiptAtIndex", + "nameLocation": "3313:17:3", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1846, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1843, + "mutability": "mutable", + "name": "queue", + "nameLocation": "3378:5:3", + "nodeType": "VariableDeclaration", + "scope": 1869, + "src": "3340:43:3", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + }, + "typeName": + { + "id": 1842, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1841, + "name": "TeleporterMessageReceiptQueue", + "nameLocations": + [ + "3340:29:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1684, + "src": "3340:29:3" + }, + "referencedDeclaration": 1684, + "src": "3340:29:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1845, + "mutability": "mutable", + "name": "index", + "nameLocation": "3401:5:3", + "nodeType": "VariableDeclaration", + "scope": 1869, + "src": "3393:13:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1844, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3393:7:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3330:82:3" + }, + "returnParameters": + { + "id": 1850, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1849, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1869, + "src": "3436:31:3", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt" + }, + "typeName": + { + "id": 1848, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1847, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "3436:24:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "3436:24:3" + }, + "referencedDeclaration": 1396, + "src": "3436:24:3", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "visibility": "internal" + } + ], + "src": "3435:33:3" + }, + "scope": 1870, + "src": "3304:295:3", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 1871, + "src": "669:2986:3", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "145:3511:3" + }, + "id": 3 + }, + "icm-contracts/contracts/teleporter/TeleporterMessenger.sol": + { + "AST": + { + "absolutePath": "icm-contracts/contracts/teleporter/TeleporterMessenger.sol", + "exportedSymbols": + { + "IERC20": + [ + 2099 + ], + "ITeleporterMessenger": + [ + 1653 + ], + "ITeleporterReceiver": + [ + 1667 + ], + "IWarpMessenger": + [ + 1389 + ], + "ReceiptQueue": + [ + 1870 + ], + "ReentrancyGuards": + [ + 1934 + ], + "SafeERC20": + [ + 2389 + ], + "SafeERC20TransferFrom": + [ + 2021 + ], + "TeleporterFeeInfo": + [ + 1436 + ], + "TeleporterMessage": + [ + 1431 + ], + "TeleporterMessageInput": + [ + 1411 + ], + "TeleporterMessageReceipt": + [ + 1396 + ], + "TeleporterMessenger": + [ + 1334 + ], + "WarpMessage": + [ + 1343 + ] + }, + "id": 1335, + "license": "LicenseRef-Ecosystem", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1, + "literals": + [ + "solidity", + "0.8", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "145:23:4" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol", + "file": "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol", + "id": 3, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 2100, + "src": "170:76:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 2, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2099, + "src": "178:6:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol", + "file": "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol", + "id": 5, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 2390, + "src": "247:88:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 4, + "name": "SafeERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2389, + "src": "255:9:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/contracts/subnet-evm/IWarpMessenger.sol", + "file": "@subnet-evm/IWarpMessenger.sol", + "id": 8, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 1390, + "src": "336:75:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 6, + "name": "WarpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1343, + "src": "344:11:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + }, + { + "foreign": + { + "id": 7, + "name": "IWarpMessenger", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1389, + "src": "357:14:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/contracts/teleporter/ITeleporterMessenger.sol", + "file": "./ITeleporterMessenger.sol", + "id": 14, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 1654, + "src": "412:174:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 9, + "name": "TeleporterMessageReceipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1396, + "src": "425:24:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + }, + { + "foreign": + { + "id": 10, + "name": "TeleporterMessageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1411, + "src": "455:22:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + }, + { + "foreign": + { + "id": 11, + "name": "TeleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1431, + "src": "483:17:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + }, + { + "foreign": + { + "id": 12, + "name": "TeleporterFeeInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1436, + "src": "506:17:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + }, + { + "foreign": + { + "id": 13, + "name": "ITeleporterMessenger", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1653, + "src": "529:20:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/contracts/teleporter/ReceiptQueue.sol", + "file": "./ReceiptQueue.sol", + "id": 16, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 1871, + "src": "587:48:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 15, + "name": "ReceiptQueue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1870, + "src": "595:12:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol", + "file": "@utilities/SafeERC20TransferFrom.sol", + "id": 18, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 2022, + "src": "636:75:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 17, + "name": "SafeERC20TransferFrom", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "644:21:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/contracts/teleporter/ITeleporterReceiver.sol", + "file": "./ITeleporterReceiver.sol", + "id": 20, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 1668, + "src": "712:62:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 19, + "name": "ITeleporterReceiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1667, + "src": "720:19:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/contracts/utilities/ReentrancyGuards.sol", + "file": "@utilities/ReentrancyGuards.sol", + "id": 22, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1335, + "sourceUnit": 1935, + "src": "775:65:4", + "symbolAliases": + [ + { + "foreign": + { + "id": 21, + "name": "ReentrancyGuards", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1934, + "src": "783:16:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 24, + "name": "ITeleporterMessenger", + "nameLocations": + [ + "1355:20:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1653, + "src": "1355:20:4" + }, + "id": 25, + "nodeType": "InheritanceSpecifier", + "src": "1355:20:4" + }, + { + "baseName": + { + "id": 26, + "name": "ReentrancyGuards", + "nameLocations": + [ + "1377:16:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1934, + "src": "1377:16:4" + }, + "id": 27, + "nodeType": "InheritanceSpecifier", + "src": "1377:16:4" + } + ], + "canonicalName": "TeleporterMessenger", + "contractDependencies": [], + "contractKind": "contract", + "documentation": + { + "id": 23, + "nodeType": "StructuredDocumentation", + "src": "842:480:4", + "text": " @dev Implementation of the {ITeleporterMessenger} interface.\n This implementation is used to send messages cross chain using the IWarpMessenger precompile,\n and to receive messages sent from other chains. Teleporter contracts should be deployed through Nick's method\n of universal deployer, such that the same contract is deployed at the same address on all chains.\n @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md" + }, + "fullyImplemented": true, + "id": 1334, + "linearizedBaseContracts": + [ + 1334, + 1934, + 1653 + ], + "name": "TeleporterMessenger", + "nameLocation": "1332:19:4", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "global": false, + "id": 31, + "libraryName": + { + "id": 28, + "name": "SafeERC20", + "nameLocations": + [ + "1406:9:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2389, + "src": "1406:9:4" + }, + "nodeType": "UsingForDirective", + "src": "1400:27:4", + "typeName": + { + "id": 30, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 29, + "name": "IERC20", + "nameLocations": + [ + "1420:6:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "1420:6:4" + }, + "referencedDeclaration": 2099, + "src": "1420:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + } + }, + { + "global": false, + "id": 35, + "libraryName": + { + "id": 32, + "name": "ReceiptQueue", + "nameLocations": + [ + "1438:12:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1870, + "src": "1438:12:4" + }, + "nodeType": "UsingForDirective", + "src": "1432:66:4", + "typeName": + { + "id": 34, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 33, + "name": "ReceiptQueue.TeleporterMessageReceiptQueue", + "nameLocations": + [ + "1455:12:4", + "1468:29:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1684, + "src": "1455:42:4" + }, + "referencedDeclaration": 1684, + "src": "1455:42:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + } + } + }, + { + "canonicalName": "TeleporterMessenger.SentMessageInfo", + "documentation": + { + "id": 36, + "nodeType": "StructuredDocumentation", + "src": "1504:163:4", + "text": " @notice SentMessageInfo includes the fee information for a given message submitted\n to be sent, along with the hash of the message itself." + }, + "id": 42, + "members": + [ + { + "constant": false, + "id": 38, + "mutability": "mutable", + "name": "messageHash", + "nameLocation": "1713:11:4", + "nodeType": "VariableDeclaration", + "scope": 42, + "src": "1705:19:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 37, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1705:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 41, + "mutability": "mutable", + "name": "feeInfo", + "nameLocation": "1752:7:4", + "nodeType": "VariableDeclaration", + "scope": 42, + "src": "1734:25:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 40, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 39, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "1734:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "1734:17:4" + }, + "referencedDeclaration": 1436, + "src": "1734:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + } + ], + "name": "SentMessageInfo", + "nameLocation": "1679:15:4", + "nodeType": "StructDefinition", + "scope": 1334, + "src": "1672:94:4", + "visibility": "public" + }, + { + "constant": true, + "documentation": + { + "id": 43, + "nodeType": "StructuredDocumentation", + "src": "1772:88:4", + "text": " @notice Warp precompile used for sending and receiving Warp messages." + }, + "functionSelector": "b771b3bc", + "id": 49, + "mutability": "constant", + "name": "WARP_MESSENGER", + "nameLocation": "1896:14:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "1865:114:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IWarpMessenger_$1389", + "typeString": "contract IWarpMessenger" + }, + "typeName": + { + "id": 45, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 44, + "name": "IWarpMessenger", + "nameLocations": + [ + "1865:14:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1389, + "src": "1865:14:4" + }, + "referencedDeclaration": 1389, + "src": "1865:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IWarpMessenger_$1389", + "typeString": "contract IWarpMessenger" + } + }, + "value": + { + "arguments": + [ + { + "hexValue": "307830323030303030303030303030303030303030303030303030303030303030303030303030303035", + "id": 47, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1936:42:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "value": "0x0200000000000000000000000000000000000005" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 46, + "name": "IWarpMessenger", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1389, + "src": "1921:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_IWarpMessenger_$1389_$", + "typeString": "type(contract IWarpMessenger)" + } + }, + "id": 48, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1921:58:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IWarpMessenger_$1389", + "typeString": "contract IWarpMessenger" + } + }, + "visibility": "public" + }, + { + "constant": false, + "documentation": + { + "id": 50, + "nodeType": "StructuredDocumentation", + "src": "1986:255:4", + "text": " @notice The blockchain ID of the chain the contract is deployed on.\n @dev Can be initialized by calling initializeBlockchainID, or will be initialized\n automatically on the first successful call to send or receive a message." + }, + "functionSelector": "d127dc9b", + "id": 52, + "mutability": "mutable", + "name": "blockchainID", + "nameLocation": "2261:12:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "2246:27:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 51, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2246:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "public" + }, + { + "constant": false, + "documentation": + { + "id": 53, + "nodeType": "StructuredDocumentation", + "src": "2280:378:4", + "text": " @notice A monotonically incremented integer tracking the total number of messages sent by this TeleporterMessenger contract.\n @dev Used to provide uniqueness when generating message IDs for new messages. The first message sent will use a\n messageNonce of 1 such that the nonce value can be used to provide replay protection for a given message ID." + }, + "functionSelector": "ecc70428", + "id": 55, + "mutability": "mutable", + "name": "messageNonce", + "nameLocation": "2678:12:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "2663:27:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 54, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2663:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "public" + }, + { + "constant": false, + "documentation": + { + "id": 56, + "nodeType": "StructuredDocumentation", + "src": "2697:283:4", + "text": " @notice Tracks the outstanding receipts to send back to a given chain in subsequent messages sent to that chain.\n @dev The key is the blockchain ID of the other chain, and the value is a queue of pending receipts for messages\n received from that chain." + }, + "functionSelector": "e6e67bd5", + "id": 61, + "mutability": "mutable", + "name": "receiptQueues", + "nameLocation": "3095:13:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "2985:123:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_$", + "typeString": "mapping(bytes32 => struct ReceiptQueue.TeleporterMessageReceiptQueue)" + }, + "typeName": + { + "id": 60, + "keyName": "sourceBlockchainID", + "keyNameLocation": "3001:18:4", + "keyType": + { + "id": 57, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2993:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "2985:94:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_$", + "typeString": "mapping(bytes32 => struct ReceiptQueue.TeleporterMessageReceiptQueue)" + }, + "valueName": "receiptQueue", + "valueNameLocation": "3066:12:4", + "valueType": + { + "id": 59, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 58, + "name": "ReceiptQueue.TeleporterMessageReceiptQueue", + "nameLocations": + [ + "3023:12:4", + "3036:29:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1684, + "src": "3023:42:4" + }, + "referencedDeclaration": 1684, + "src": "3023:42:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue" + } + } + }, + "visibility": "public" + }, + { + "constant": false, + "documentation": + { + "id": 62, + "nodeType": "StructuredDocumentation", + "src": "3115:249:4", + "text": " @notice Tracks the message hash and fee information for each message sent that has yet to be acknowledged\n with a receipt.\n @dev The key is the message ID, and the value is the info for the uniquely identified message." + }, + "functionSelector": "2ca40f55", + "id": 67, + "mutability": "mutable", + "name": "sentMessageInfo", + "nameLocation": "3434:15:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "3369:80:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo)" + }, + "typeName": + { + "id": 66, + "keyName": "messageID", + "keyNameLocation": "3385:9:4", + "keyType": + { + "id": 63, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3377:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3369:57:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo)" + }, + "valueName": "messageInfo", + "valueNameLocation": "3414:11:4", + "valueType": + { + "id": 65, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 64, + "name": "SentMessageInfo", + "nameLocations": + [ + "3398:15:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 42, + "src": "3398:15:4" + }, + "referencedDeclaration": 42, + "src": "3398:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo" + } + } + }, + "visibility": "public" + }, + { + "constant": false, + "documentation": + { + "id": 68, + "nodeType": "StructuredDocumentation", + "src": "3456:373:4", + "text": " @notice Tracks the hash of messages that have been received but have never succeeded in execution.\n @dev Enables retrying of failed messages with higher gas limits. Message execution is guaranteed to\n succeed at most once. The key is the message ID, and the value is the hash of the uniquely\n identified message whose execution failed." + }, + "functionSelector": "860a3b06", + "id": 72, + "mutability": "mutable", + "name": "receivedFailedMessageHashes", + "nameLocation": "3891:27:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "3834:84:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bytes32_$", + "typeString": "mapping(bytes32 => bytes32)" + }, + "typeName": + { + "id": 71, + "keyName": "messageID", + "keyNameLocation": "3850:9:4", + "keyType": + { + "id": 69, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3842:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "3834:49:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bytes32_$", + "typeString": "mapping(bytes32 => bytes32)" + }, + "valueName": "messageHash", + "valueNameLocation": "3871:11:4", + "valueType": + { + "id": 70, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3863:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + }, + "visibility": "public" + }, + { + "constant": false, + "documentation": + { + "id": 73, + "nodeType": "StructuredDocumentation", + "src": "3925:312:4", + "text": " @dev Tracks the message nonce for each message that has been received. The key is the message ID,\n and the value is the nonce value that was received as a part of that message.\n Note: the `messageNonce` values are also used to determine if a given message has been received or not." + }, + "id": 77, + "mutability": "mutable", + "name": "_receivedMessageNonces", + "nameLocation": "4302:22:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "4242:82:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_uint256_$", + "typeString": "mapping(bytes32 => uint256)" + }, + "typeName": + { + "id": 76, + "keyName": "messageID", + "keyNameLocation": "4258:9:4", + "keyType": + { + "id": 74, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4250:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "4242:50:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_uint256_$", + "typeString": "mapping(bytes32 => uint256)" + }, + "valueName": "messageNonce", + "valueNameLocation": "4279:12:4", + "valueType": + { + "id": 75, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4271:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + "visibility": "internal" + }, + { + "constant": false, + "documentation": + { + "id": 78, + "nodeType": "StructuredDocumentation", + "src": "4331:210:4", + "text": " @dev Tracks the relayer reward address for each message that has been received.\n The key is the message ID, and the value is the reward address provided by the deliverer of the message." + }, + "id": 82, + "mutability": "mutable", + "name": "_relayerRewardAddresses", + "nameLocation": "4614:23:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "4546:91:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_address_$", + "typeString": "mapping(bytes32 => address)" + }, + "typeName": + { + "id": 81, + "keyName": "messageID", + "keyNameLocation": "4562:9:4", + "keyType": + { + "id": 79, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4554:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Mapping", + "src": "4546:58:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_address_$", + "typeString": "mapping(bytes32 => address)" + }, + "valueName": "relayerRewardAddress", + "valueNameLocation": "4583:20:4", + "valueType": + { + "id": 80, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4575:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + }, + "visibility": "internal" + }, + { + "constant": false, + "documentation": + { + "id": 83, + "nodeType": "StructuredDocumentation", + "src": "4644:284:4", + "text": " @dev Tracks the reward amounts for a given asset able to be redeemed by a given relayer.\n The first key is the relayer reward address, the second key is the fee token contract address,\n and the value is the amount of the asset redeemable by the relayer." + }, + "id": 89, + "mutability": "mutable", + "name": "_relayerRewardAmounts", + "nameLocation": "5077:21:4", + "nodeType": "VariableDeclaration", + "scope": 1334, + "src": "4933:165:4", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + }, + "typeName": + { + "id": 88, + "keyName": "relayerRewardAddress", + "keyNameLocation": "4958:20:4", + "keyType": + { + "id": 84, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4950:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "4933:134:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + }, + "valueName": "", + "valueNameLocation": "-1:-1:-1", + "valueType": + { + "id": 87, + "keyName": "feeTokenContract", + "keyNameLocation": "5010:16:4", + "keyType": + { + "id": 85, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5002:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "4994:67:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + }, + "valueName": "redeemableRewardAmount", + "valueNameLocation": "5038:22:4", + "valueType": + { + "id": 86, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5030:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + } + }, + "visibility": "internal" + }, + { + "baseFunctions": + [ + 1524 + ], + "body": + { + "id": 110, + "nodeType": "Block", + "src": "5575:403:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 101, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 93, + "src": "5853:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_calldata_ptr", + "typeString": "struct TeleporterMessageInput calldata" + } + }, + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "expression": + { + "baseExpression": + { + "id": 102, + "name": "receiptQueues", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 61, + "src": "5879:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_$", + "typeString": "mapping(bytes32 => struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref)" + } + }, + "id": 105, + "indexExpression": + { + "expression": + { + "id": 103, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 93, + "src": "5893:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_calldata_ptr", + "typeString": "struct TeleporterMessageInput calldata" + } + }, + "id": 104, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5906:23:4", + "memberName": "destinationBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1398, + "src": "5893:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "5879:51:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref" + } + }, + "id": 106, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5931:28:4", + "memberName": "getOutstandingReceiptsToSend", + "nodeType": "MemberAccess", + "referencedDeclaration": 1823, + "src": "5879:80:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$returns$_t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr_$attached_to$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$", + "typeString": "function (struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer) returns (struct TeleporterMessageReceipt memory[] memory)" + } + }, + "id": 107, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5879:82:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_calldata_ptr", + "typeString": "struct TeleporterMessageInput calldata" + }, + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + ], + "id": 100, + "name": "_sendTeleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1108, + "src": "5817:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_struct$_TeleporterMessageInput_$1411_memory_ptr_$_t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (struct TeleporterMessageInput memory,struct TeleporterMessageReceipt memory[] memory) returns (bytes32)" + } + }, + "id": 108, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5817:154:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 99, + "id": 109, + "nodeType": "Return", + "src": "5810:161:4" + } + ] + }, + "documentation": + { + "id": 90, + "nodeType": "StructuredDocumentation", + "src": "5105:328:4", + "text": " @dev See {ITeleporterMessenger-sendCrossChainMessage}\n When executed, a relayer may kick off an asynchronous event to have the validators of the\n chain create an aggregate BLS signature of the message.\n Emits a {SendCrossChainMessage} event when message successfully gets sent." + }, + "functionSelector": "62448850", + "id": 111, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "id": 96, + "kind": "modifierInvocation", + "modifierName": + { + "id": 95, + "name": "senderNonReentrant", + "nameLocations": + [ + "5538:18:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1902, + "src": "5538:18:4" + }, + "nodeType": "ModifierInvocation", + "src": "5538:18:4" + } + ], + "name": "sendCrossChainMessage", + "nameLocation": "5447:21:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 94, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 93, + "mutability": "mutable", + "name": "messageInput", + "nameLocation": "5510:12:4", + "nodeType": "VariableDeclaration", + "scope": 111, + "src": "5478:44:4", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_calldata_ptr", + "typeString": "struct TeleporterMessageInput" + }, + "typeName": + { + "id": 92, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 91, + "name": "TeleporterMessageInput", + "nameLocations": + [ + "5478:22:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1411, + "src": "5478:22:4" + }, + "referencedDeclaration": 1411, + "src": "5478:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_storage_ptr", + "typeString": "struct TeleporterMessageInput" + } + }, + "visibility": "internal" + } + ], + "src": "5468:60:4" + }, + "returnParameters": + { + "id": 99, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 98, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 111, + "src": "5566:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 97, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5566:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "5565:9:4" + }, + "scope": 1334, + "src": "5438:540:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1531 + ], + "body": + { + "id": 180, + "nodeType": "Block", + "src": "6355:1590:4", + "statements": + [ + { + "assignments": + [ + 121 + ], + "declarations": + [ + { + "constant": false, + "id": 121, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "6694:9:4", + "nodeType": "VariableDeclaration", + "scope": 180, + "src": "6686:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 120, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "6686:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 129, + "initialValue": + { + "arguments": + [ + { + "id": 123, + "name": "blockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 52, + "src": "6737:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 124, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 115, + "src": "6751:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 125, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6759:23:4", + "memberName": "destinationBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1417, + "src": "6751:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 126, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 115, + "src": "6784:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 127, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6792:12:4", + "memberName": "messageNonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 1413, + "src": "6784:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 122, + "name": "calculateMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 928, + "src": "6718:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32,uint256) view returns (bytes32)" + } + }, + "id": 128, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6718:87:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "6686:119:4" + }, + { + "assignments": + [ + 132 + ], + "declarations": + [ + { + "constant": false, + "id": 132, + "mutability": "mutable", + "name": "existingMessageInfo", + "nameLocation": "6888:19:4", + "nodeType": "VariableDeclaration", + "scope": 180, + "src": "6865:42:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo" + }, + "typeName": + { + "id": 131, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 130, + "name": "SentMessageInfo", + "nameLocations": + [ + "6865:15:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 42, + "src": "6865:15:4" + }, + "referencedDeclaration": 42, + "src": "6865:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo" + } + }, + "visibility": "internal" + } + ], + "id": 136, + "initialValue": + { + "baseExpression": + { + "id": 133, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "6910:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 135, + "indexExpression": + { + "id": 134, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 121, + "src": "6926:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "6910:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "6865:71:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 144, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 138, + "name": "existingMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 132, + "src": "7035:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "id": 139, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7055:11:4", + "memberName": "messageHash", + "nodeType": "MemberAccess", + "referencedDeclaration": 38, + "src": "7035:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 142, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7078:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 141, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "7070:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": + { + "id": 140, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7070:7:4", + "typeDescriptions": {} + } + }, + "id": 143, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7070:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "7035:45:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a206d657373616765206e6f7420666f756e64", + "id": 145, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7082:40:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_199fbf667868513fdcfeb4133baa4bac2a64719285610cf7dd50a36abe28043a", + "typeString": "literal_string \"TeleporterMessenger: message not found\"" + }, + "value": "TeleporterMessenger: message not found" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_199fbf667868513fdcfeb4133baa4bac2a64719285610cf7dd50a36abe28043a", + "typeString": "literal_string \"TeleporterMessenger: message not found\"" + } + ], + "id": 137, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "7014:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7014:118:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 147, + "nodeType": "ExpressionStatement", + "src": "7014:118:4" + }, + { + "assignments": + [ + 149 + ], + "declarations": + [ + { + "constant": false, + "id": 149, + "mutability": "mutable", + "name": "messageBytes", + "nameLocation": "7258:12:4", + "nodeType": "VariableDeclaration", + "scope": 180, + "src": "7245:25:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 148, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "7245:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 154, + "initialValue": + { + "arguments": + [ + { + "id": 152, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 115, + "src": "7284:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + ], + "expression": + { + "id": 150, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "7273:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 151, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "7277:6:4", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "7273:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 153, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7273:19:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7245:47:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 161, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 157, + "name": "messageBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 149, + "src": "7333:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 156, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "7323:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 158, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7323:23:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "expression": + { + "id": 159, + "name": "existingMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 132, + "src": "7350:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "id": 160, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7370:11:4", + "memberName": "messageHash", + "nodeType": "MemberAccess", + "referencedDeclaration": 38, + "src": "7350:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "7323:58:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20696e76616c6964206d6573736167652068617368", + "id": 162, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7395:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_26676139843dc31081160e94c107767332aeb22512cc2cec1c0677f4002ae00b", + "typeString": "literal_string \"TeleporterMessenger: invalid message hash\"" + }, + "value": "TeleporterMessenger: invalid message hash" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_26676139843dc31081160e94c107767332aeb22512cc2cec1c0677f4002ae00b", + "typeString": "literal_string \"TeleporterMessenger: invalid message hash\"" + } + ], + "id": 155, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "7302:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 163, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7302:146:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 164, + "nodeType": "ExpressionStatement", + "src": "7302:146:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 166, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 121, + "src": "7657:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 167, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 115, + "src": "7668:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 168, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7676:23:4", + "memberName": "destinationBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1417, + "src": "7668:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 169, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 115, + "src": "7701:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + { + "expression": + { + "id": 170, + "name": "existingMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 132, + "src": "7710:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "id": 171, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7730:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "7710:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + }, + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + ], + "id": 165, + "name": "SendCrossChainMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1455, + "src": "7622:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$_t_struct$_TeleporterMessage_$1431_memory_ptr_$_t_struct$_TeleporterFeeInfo_$1436_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,struct TeleporterMessage memory,struct TeleporterFeeInfo memory)" + } + }, + "id": 172, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7622:125:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 173, + "nodeType": "EmitStatement", + "src": "7617:130:4" + }, + { + "expression": + { + "arguments": + [ + { + "id": 177, + "name": "messageBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 149, + "src": "7925:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "id": 174, + "name": "WARP_MESSENGER", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49, + "src": "7894:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IWarpMessenger_$1389", + "typeString": "contract IWarpMessenger" + } + }, + "id": 176, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7909:15:4", + "memberName": "sendWarpMessage", + "nodeType": "MemberAccess", + "referencedDeclaration": 1363, + "src": "7894:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) external returns (bytes32)" + } + }, + "id": 178, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7894:44:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 179, + "nodeType": "ExpressionStatement", + "src": "7894:44:4" + } + ] + }, + "documentation": + { + "id": 112, + "nodeType": "StructuredDocumentation", + "src": "5984:252:4", + "text": " @dev Emits a {SendCrossChainMessage} event.\n Requirements:\n - `message` must have been previously sent.\n - `message` encoding must match previously sent message.\n @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "8245a1b0", + "id": 181, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "id": 118, + "kind": "modifierInvocation", + "modifierName": + { + "id": 117, + "name": "senderNonReentrant", + "nameLocations": + [ + "6336:18:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1902, + "src": "6336:18:4" + }, + "nodeType": "ModifierInvocation", + "src": "6336:18:4" + } + ], + "name": "retrySendCrossChainMessage", + "nameLocation": "6250:26:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 116, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 115, + "mutability": "mutable", + "name": "message", + "nameLocation": "6313:7:4", + "nodeType": "VariableDeclaration", + "scope": 181, + "src": "6286:34:4", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 114, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 113, + "name": "TeleporterMessage", + "nameLocations": + [ + "6286:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "6286:17:4" + }, + "referencedDeclaration": 1431, + "src": "6286:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "6276:50:4" + }, + "returnParameters": + { + "id": 119, + "nodeType": "ParameterList", + "parameters": [], + "src": "6355:0:4" + }, + "scope": 1334, + "src": "6241:1704:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1541 + ], + "body": + { + "id": 262, + "nodeType": "Block", + "src": "8791:1789:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 198, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 196, + "name": "additionalFeeAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 188, + "src": "8864:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 197, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8886:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "8864:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a207a65726f206164646974696f6e616c2066656520616d6f756e74", + "id": 199, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8889:49:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_8c0271fa956ed439c82b6287fb02448573d5bc42655257c12237badbdf20be98", + "typeString": "literal_string \"TeleporterMessenger: zero additional fee amount\"" + }, + "value": "TeleporterMessenger: zero additional fee amount" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_8c0271fa956ed439c82b6287fb02448573d5bc42655257c12237badbdf20be98", + "typeString": "literal_string \"TeleporterMessenger: zero additional fee amount\"" + } + ], + "id": 195, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "8856:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 200, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8856:83:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 201, + "nodeType": "ExpressionStatement", + "src": "8856:83:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 208, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 203, + "name": "feeTokenAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 186, + "src": "9042:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 206, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9069:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 205, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "9061:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 204, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9061:7:4", + "typeDescriptions": {} + } + }, + "id": 207, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9061:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "9042:29:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a207a65726f2066656520617373657420636f6e74726163742061646472657373", + "id": 209, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9073:54:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_f59603fcdda5ee2bb2d0f07d6e9b43b5bb3ed9ab2df0ad87d6ed06efd082db17", + "typeString": "literal_string \"TeleporterMessenger: zero fee asset contract address\"" + }, + "value": "TeleporterMessenger: zero fee asset contract address" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f59603fcdda5ee2bb2d0f07d6e9b43b5bb3ed9ab2df0ad87d6ed06efd082db17", + "typeString": "literal_string \"TeleporterMessenger: zero fee asset contract address\"" + } + ], + "id": 202, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "9021:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 210, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9021:116:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 211, + "nodeType": "ExpressionStatement", + "src": "9021:116:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 221, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "baseExpression": + { + "id": 213, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "9409:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 215, + "indexExpression": + { + "id": 214, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 184, + "src": "9425:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9409:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "id": 216, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "9436:11:4", + "memberName": "messageHash", + "nodeType": "MemberAccess", + "referencedDeclaration": 38, + "src": "9409:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 219, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9459:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 218, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "9451:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": + { + "id": 217, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9451:7:4", + "typeDescriptions": {} + } + }, + "id": 220, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9451:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "9409:52:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a206d657373616765206e6f7420666f756e64", + "id": 222, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9475:40:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_199fbf667868513fdcfeb4133baa4bac2a64719285610cf7dd50a36abe28043a", + "typeString": "literal_string \"TeleporterMessenger: message not found\"" + }, + "value": "TeleporterMessenger: message not found" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_199fbf667868513fdcfeb4133baa4bac2a64719285610cf7dd50a36abe28043a", + "typeString": "literal_string \"TeleporterMessenger: message not found\"" + } + ], + "id": 212, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "9388:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 223, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9388:137:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 224, + "nodeType": "ExpressionStatement", + "src": "9388:137:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 232, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "baseExpression": + { + "id": 226, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "10005:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 228, + "indexExpression": + { + "id": 227, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 184, + "src": "10021:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10005:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "id": 229, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10032:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "10005:34:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage", + "typeString": "struct TeleporterFeeInfo storage ref" + } + }, + "id": 230, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10040:15:4", + "memberName": "feeTokenAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1433, + "src": "10005:50:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "id": 231, + "name": "feeTokenAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 186, + "src": "10059:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "10005:69:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20696e76616c69642066656520617373657420636f6e74726163742061646472657373", + "id": 233, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10088:57:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_6812da3988bd2f77d1ddd48d5fb48c13b77f36ca500fc816a9e31b938ca217f4", + "typeString": "literal_string \"TeleporterMessenger: invalid fee asset contract address\"" + }, + "value": "TeleporterMessenger: invalid fee asset contract address" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_6812da3988bd2f77d1ddd48d5fb48c13b77f36ca500fc816a9e31b938ca217f4", + "typeString": "literal_string \"TeleporterMessenger: invalid fee asset contract address\"" + } + ], + "id": 225, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "9984:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 234, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9984:171:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 235, + "nodeType": "ExpressionStatement", + "src": "9984:171:4" + }, + { + "assignments": + [ + 237 + ], + "declarations": + [ + { + "constant": false, + "id": 237, + "mutability": "mutable", + "name": "adjustedAmount", + "nameLocation": "10249:14:4", + "nodeType": "VariableDeclaration", + "scope": 262, + "src": "10241:22:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 236, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10241:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 245, + "initialValue": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 241, + "name": "feeTokenAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 186, + "src": "10324:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 240, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2099, + "src": "10317:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_IERC20_$2099_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 242, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "10317:23:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "id": 243, + "name": "additionalFeeAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 188, + "src": "10342:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": + { + "id": 238, + "name": "SafeERC20TransferFrom", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "10278:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_SafeERC20TransferFrom_$2021_$", + "typeString": "type(library SafeERC20TransferFrom)" + } + }, + "id": 239, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10300:16:4", + "memberName": "safeTransferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 1964, + "src": "10278:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (contract IERC20,uint256) returns (uint256)" + } + }, + "id": 244, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "10278:84:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10241:121:4" + }, + { + "expression": + { + "id": 252, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "expression": + { + "expression": + { + "baseExpression": + { + "id": 246, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "10439:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 248, + "indexExpression": + { + "id": 247, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 184, + "src": "10455:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10439:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "id": 249, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10466:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "10439:34:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage", + "typeString": "struct TeleporterFeeInfo storage ref" + } + }, + "id": 250, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberLocation": "10474:6:4", + "memberName": "amount", + "nodeType": "MemberAccess", + "referencedDeclaration": 1435, + "src": "10439:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "id": 251, + "name": "adjustedAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 237, + "src": "10484:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10439:59:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 253, + "nodeType": "ExpressionStatement", + "src": "10439:59:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 255, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 184, + "src": "10527:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "baseExpression": + { + "id": 256, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "10538:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 258, + "indexExpression": + { + "id": 257, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 184, + "src": "10554:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10538:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "id": 259, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10565:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "10538:34:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage", + "typeString": "struct TeleporterFeeInfo storage ref" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage", + "typeString": "struct TeleporterFeeInfo storage ref" + } + ], + "id": 254, + "name": "AddFeeAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1463, + "src": "10514:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_struct$_TeleporterFeeInfo_$1436_memory_ptr_$returns$__$", + "typeString": "function (bytes32,struct TeleporterFeeInfo memory)" + } + }, + "id": 260, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "10514:59:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 261, + "nodeType": "EmitStatement", + "src": "10509:64:4" + } + ] + }, + "documentation": + { + "id": 182, + "nodeType": "StructuredDocumentation", + "src": "7951:661:4", + "text": " @dev Both `senderNonReentrant` and `receiverNonReentrant` are used here to prevent the\n external call of `safeTransferFrom` from being reentrant, calling `receiveCrossChainMessage`\n to attribute rewards for this message, and then still adding fee amount for this message.\n Emits an {AddFeeAmount} event.\n Requirements:\n - `additionalFeeAmount` must be non-zero.\n - `message` must exist and not have been acknowledged with a receipt yet.\n - `feeTokenAddress` must match the fee asset contract address used in the original call to `sendCrossChainMessage`.\n @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "8ac0fd04", + "id": 263, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "id": 191, + "kind": "modifierInvocation", + "modifierName": + { + "id": 190, + "name": "senderNonReentrant", + "nameLocations": + [ + "8751:18:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1902, + "src": "8751:18:4" + }, + "nodeType": "ModifierInvocation", + "src": "8751:18:4" + }, + { + "id": 193, + "kind": "modifierInvocation", + "modifierName": + { + "id": 192, + "name": "receiverNonReentrant", + "nameLocations": + [ + "8770:20:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1921, + "src": "8770:20:4" + }, + "nodeType": "ModifierInvocation", + "src": "8770:20:4" + } + ], + "name": "addFeeAmount", + "nameLocation": "8626:12:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 189, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 184, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "8656:9:4", + "nodeType": "VariableDeclaration", + "scope": 263, + "src": "8648:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 183, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8648:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 186, + "mutability": "mutable", + "name": "feeTokenAddress", + "nameLocation": "8683:15:4", + "nodeType": "VariableDeclaration", + "scope": 263, + "src": "8675:23:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 185, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8675:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 188, + "mutability": "mutable", + "name": "additionalFeeAmount", + "nameLocation": "8716:19:4", + "nodeType": "VariableDeclaration", + "scope": 263, + "src": "8708:27:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 187, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8708:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "8638:103:4" + }, + "returnParameters": + { + "id": 194, + "nodeType": "ParameterList", + "parameters": [], + "src": "8791:0:4" + }, + "scope": 1334, + "src": "8617:1963:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1549 + ], + "body": + { + "id": 434, + "nodeType": "Block", + "src": "11510:3496:4", + "statements": + [ + { + "assignments": + [ + 275, + 277 + ], + "declarations": + [ + { + "constant": false, + "id": 275, + "mutability": "mutable", + "name": "warpMessage", + "nameLocation": "11678:11:4", + "nodeType": "VariableDeclaration", + "scope": 434, + "src": "11659:30:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage" + }, + "typeName": + { + "id": 274, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 273, + "name": "WarpMessage", + "nameLocations": + [ + "11659:11:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1343, + "src": "11659:11:4" + }, + "referencedDeclaration": 1343, + "src": "11659:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_storage_ptr", + "typeString": "struct WarpMessage" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 277, + "mutability": "mutable", + "name": "success", + "nameLocation": "11696:7:4", + "nodeType": "VariableDeclaration", + "scope": 434, + "src": "11691:12:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 276, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "11691:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 282, + "initialValue": + { + "arguments": + [ + { + "id": 280, + "name": "messageIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 266, + "src": "11757:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + ], + "expression": + { + "id": 278, + "name": "WARP_MESSENGER", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49, + "src": "11719:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IWarpMessenger_$1389", + "typeString": "contract IWarpMessenger" + } + }, + "id": 279, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "11734:22:4", + "memberName": "getVerifiedWarpMessage", + "nodeType": "MemberAccess", + "referencedDeclaration": 1373, + "src": "11719:37:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$_t_uint32_$returns$_t_struct$_WarpMessage_$1343_memory_ptr_$_t_bool_$", + "typeString": "function (uint32) view external returns (struct WarpMessage memory,bool)" + } + }, + "id": 281, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "11719:51:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_struct$_WarpMessage_$1343_memory_ptr_$_t_bool_$", + "typeString": "tuple(struct WarpMessage memory,bool)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11658:112:4" + }, + { + "expression": + { + "arguments": + [ + { + "id": 284, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 277, + "src": "11788:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20696e76616c69642077617270206d657373616765", + "id": 285, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11797:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_e5c6335fdbfc2dee5e3d32e6310ded1286aa27247680d4aeacf28724b3ee8a92", + "typeString": "literal_string \"TeleporterMessenger: invalid warp message\"" + }, + "value": "TeleporterMessenger: invalid warp message" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e5c6335fdbfc2dee5e3d32e6310ded1286aa27247680d4aeacf28724b3ee8a92", + "typeString": "literal_string \"TeleporterMessenger: invalid warp message\"" + } + ], + "id": 283, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "11780:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 286, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "11780:61:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 287, + "nodeType": "ExpressionStatement", + "src": "11780:61:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 295, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 289, + "name": "warpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 275, + "src": "12309:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage memory" + } + }, + "id": 290, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "12321:19:4", + "memberName": "originSenderAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1340, + "src": "12309:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "arguments": + [ + { + "id": 293, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "12352:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_TeleporterMessenger_$1334", + "typeString": "contract TeleporterMessenger" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_TeleporterMessenger_$1334", + "typeString": "contract TeleporterMessenger" + } + ], + "id": 292, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12344:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 291, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "12344:7:4", + "typeDescriptions": {} + } + }, + "id": 294, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12344:13:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "12309:48:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20696e76616c6964206f726967696e2073656e6465722061646472657373", + "id": 296, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12371:52:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_3d9d4a5963a509462afb97b34493976d8bde9ee8b38d54a1b129acedfc342a0d", + "typeString": "literal_string \"TeleporterMessenger: invalid origin sender address\"" + }, + "value": "TeleporterMessenger: invalid origin sender address" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_3d9d4a5963a509462afb97b34493976d8bde9ee8b38d54a1b129acedfc342a0d", + "typeString": "literal_string \"TeleporterMessenger: invalid origin sender address\"" + } + ], + "id": 288, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "12288:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 297, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12288:145:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 298, + "nodeType": "ExpressionStatement", + "src": "12288:145:4" + }, + { + "assignments": + [ + 301 + ], + "declarations": + [ + { + "constant": false, + "id": 301, + "mutability": "mutable", + "name": "teleporterMessage", + "nameLocation": "12514:17:4", + "nodeType": "VariableDeclaration", + "scope": 434, + "src": "12489:42:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 300, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 299, + "name": "TeleporterMessage", + "nameLocations": + [ + "12489:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "12489:17:4" + }, + "referencedDeclaration": 1431, + "src": "12489:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "id": 309, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 304, + "name": "warpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 275, + "src": "12557:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage memory" + } + }, + "id": 305, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "12569:7:4", + "memberName": "payload", + "nodeType": "MemberAccess", + "referencedDeclaration": 1342, + "src": "12557:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "components": + [ + { + "id": 306, + "name": "TeleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1431, + "src": "12579:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_TeleporterMessage_$1431_storage_ptr_$", + "typeString": "type(struct TeleporterMessage storage pointer)" + } + } + ], + "id": 307, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "12578:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_TeleporterMessage_$1431_storage_ptr_$", + "typeString": "type(struct TeleporterMessage storage pointer)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_type$_t_struct$_TeleporterMessage_$1431_storage_ptr_$", + "typeString": "type(struct TeleporterMessage storage pointer)" + } + ], + "expression": + { + "id": 302, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "12546:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 303, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "12550:6:4", + "memberName": "decode", + "nodeType": "MemberAccess", + "src": "12546:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abidecode_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 308, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12546:52:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12489:109:4" + }, + { + "assignments": + [ + 311 + ], + "declarations": + [ + { + "constant": false, + "id": 311, + "mutability": "mutable", + "name": "blockchainID_", + "nameLocation": "12687:13:4", + "nodeType": "VariableDeclaration", + "scope": 434, + "src": "12679:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 310, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12679:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 314, + "initialValue": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 312, + "name": "initializeBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 902, + "src": "12703:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$_t_bytes32_$", + "typeString": "function () returns (bytes32)" + } + }, + "id": 313, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12703:24:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12679:48:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 319, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 316, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "12829:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 317, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "12847:23:4", + "memberName": "destinationBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1417, + "src": "12829:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "id": 318, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 311, + "src": "12874:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "12829:58:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20696e76616c69642064657374696e6174696f6e20636861696e204944", + "id": 320, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12901:51:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_730fed50616b75b2d0ba934d195c6f0aca915e81e88cc23b263e11f29f45d691", + "typeString": "literal_string \"TeleporterMessenger: invalid destination chain ID\"" + }, + "value": "TeleporterMessenger: invalid destination chain ID" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_730fed50616b75b2d0ba934d195c6f0aca915e81e88cc23b263e11f29f45d691", + "typeString": "literal_string \"TeleporterMessenger: invalid destination chain ID\"" + } + ], + "id": 315, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "12808:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 321, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12808:154:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 322, + "nodeType": "ExpressionStatement", + "src": "12808:154:4" + }, + { + "assignments": + [ + 324 + ], + "declarations": + [ + { + "constant": false, + "id": 324, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "13082:9:4", + "nodeType": "VariableDeclaration", + "scope": 434, + "src": "13074:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 323, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "13074:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 332, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 326, + "name": "warpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 275, + "src": "13126:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage memory" + } + }, + "id": 327, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13138:13:4", + "memberName": "sourceChainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1338, + "src": "13126:25:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 328, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 311, + "src": "13153:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 329, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "13168:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 330, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13186:12:4", + "memberName": "messageNonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 1413, + "src": "13168:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 325, + "name": "calculateMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 928, + "src": "13094:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32,uint256) view returns (bytes32)" + } + }, + "id": 331, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13094:114:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "13074:134:4" + }, + { + "expression": + { + "arguments": + [ + { + "id": 337, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "13297:28:4", + "subExpression": + { + "arguments": + [ + { + "id": 335, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 324, + "src": "13315:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 334, + "name": "_messageReceived", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1333, + "src": "13298:16:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (bytes32) view returns (bool)" + } + }, + "id": 336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13298:27:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a206d65737361676520616c7265616479207265636569766564", + "id": 338, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13327:47:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_9d0c87d85651afd992af0f43a407b2e116bf2abb65d3aac26ec6d09489848404", + "typeString": "literal_string \"TeleporterMessenger: message already received\"" + }, + "value": "TeleporterMessenger: message already received" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_9d0c87d85651afd992af0f43a407b2e116bf2abb65d3aac26ec6d09489848404", + "typeString": "literal_string \"TeleporterMessenger: message already received\"" + } + ], + "id": 333, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "13289:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 339, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13289:86:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 340, + "nodeType": "ExpressionStatement", + "src": "13289:86:4" + }, + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "expression": + { + "id": 343, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "13499:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 344, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13503:6:4", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "13499:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 345, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "13511:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 346, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13529:23:4", + "memberName": "allowedRelayerAddresses", + "nodeType": "MemberAccess", + "referencedDeclaration": 1424, + "src": "13511:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + ], + "id": 342, + "name": "_checkIsAllowedRelayer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 975, + "src": "13476:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_address_$_t_array$_t_address_$dyn_memory_ptr_$returns$_t_bool_$", + "typeString": "function (address,address[] memory) pure returns (bool)" + } + }, + "id": 347, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13476:77:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20756e617574686f72697a65642072656c61796572", + "id": 348, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13567:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_91ed016b14e12fc32598b19219dd95f1735a0c297f18fe54d9dc3ea62fac382e", + "typeString": "literal_string \"TeleporterMessenger: unauthorized relayer\"" + }, + "value": "TeleporterMessenger: unauthorized relayer" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_91ed016b14e12fc32598b19219dd95f1735a0c297f18fe54d9dc3ea62fac382e", + "typeString": "literal_string \"TeleporterMessenger: unauthorized relayer\"" + } + ], + "id": 341, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "13455:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 349, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13455:165:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 350, + "nodeType": "ExpressionStatement", + "src": "13455:165:4" + }, + { + "expression": + { + "arguments": + [ + { + "id": 352, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 324, + "src": "13693:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 353, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "13704:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 354, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13722:12:4", + "memberName": "messageNonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 1413, + "src": "13704:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 351, + "name": "_markMessageReceived", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1130, + "src": "13672:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,uint256)" + } + }, + "id": 355, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13672:63:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 356, + "nodeType": "ExpressionStatement", + "src": "13672:63:4" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 362, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 357, + "name": "relayerRewardAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 268, + "src": "13807:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 360, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13839:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 359, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "13831:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 358, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13831:7:4", + "typeDescriptions": {} + } + }, + "id": 361, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13831:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13807:34:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 370, + "nodeType": "IfStatement", + "src": "13803:122:4", + "trueBody": + { + "id": 369, + "nodeType": "Block", + "src": "13843:82:4", + "statements": + [ + { + "expression": + { + "id": 367, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "id": 363, + "name": "_relayerRewardAddresses", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 82, + "src": "13857:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_address_$", + "typeString": "mapping(bytes32 => address)" + } + }, + "id": 365, + "indexExpression": + { + "id": 364, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 324, + "src": "13881:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "13857:34:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 366, + "name": "relayerRewardAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 268, + "src": "13894:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13857:57:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 368, + "nodeType": "ExpressionStatement", + "src": "13857:57:4" + } + ] + } + }, + { + "assignments": + [ + 372 + ], + "declarations": + [ + { + "constant": false, + "id": 372, + "mutability": "mutable", + "name": "length", + "nameLocation": "14100:6:4", + "nodeType": "VariableDeclaration", + "scope": 434, + "src": "14092:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 371, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14092:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 376, + "initialValue": + { + "expression": + { + "expression": + { + "id": 373, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "14109:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 374, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14127:8:4", + "memberName": "receipts", + "nodeType": "MemberAccess", + "referencedDeclaration": 1428, + "src": "14109:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "id": 375, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14136:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "14109:33:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "14092:50:4" + }, + { + "body": + { + "id": 396, + "nodeType": "Block", + "src": "14185:110:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 387, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 311, + "src": "14212:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 388, + "name": "warpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 275, + "src": "14227:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage memory" + } + }, + "id": 389, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14239:13:4", + "memberName": "sourceChainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1338, + "src": "14227:25:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": + { + "expression": + { + "id": 390, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "14254:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 391, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14272:8:4", + "memberName": "receipts", + "nodeType": "MemberAccess", + "referencedDeclaration": 1428, + "src": "14254:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "id": 393, + "indexExpression": + { + "id": 392, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 378, + "src": "14281:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14254:29:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + ], + "id": 386, + "name": "_markReceipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1195, + "src": "14199:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,struct TeleporterMessageReceipt memory)" + } + }, + "id": 394, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "14199:85:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 395, + "nodeType": "ExpressionStatement", + "src": "14199:85:4" + } + ] + }, + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 382, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 380, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 378, + "src": "14168:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 381, + "name": "length", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 372, + "src": "14172:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14168:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 397, + "initializationExpression": + { + "assignments": + [ + 378 + ], + "declarations": + [ + { + "constant": false, + "id": 378, + "mutability": "mutable", + "name": "i", + "nameLocation": "14165:1:4", + "nodeType": "VariableDeclaration", + "scope": 397, + "src": "14157:9:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 377, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14157:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 379, + "nodeType": "VariableDeclarationStatement", + "src": "14157:9:4" + }, + "isSimpleCounterLoop": true, + "loopExpression": + { + "expression": + { + "id": 384, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": true, + "src": "14180:3:4", + "subExpression": + { + "id": 383, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 378, + "src": "14182:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 385, + "nodeType": "ExpressionStatement", + "src": "14180:3:4" + }, + "nodeType": "ForStatement", + "src": "14152:143:4" + }, + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "expression": + { + "id": 404, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "14487:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 405, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14505:12:4", + "memberName": "messageNonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 1413, + "src": "14487:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 406, + "name": "relayerRewardAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 268, + "src": "14557:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 403, + "name": "TeleporterMessageReceipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1396, + "src": "14422:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_TeleporterMessageReceipt_$1396_storage_ptr_$", + "typeString": "type(struct TeleporterMessageReceipt storage pointer)" + } + }, + "id": 407, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "nameLocations": + [ + "14465:20:4", + "14535:20:4" + ], + "names": + [ + "receivedMessageNonce", + "relayerRewardAddress" + ], + "nodeType": "FunctionCall", + "src": "14422:170:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + ], + "expression": + { + "baseExpression": + { + "id": 398, + "name": "receiptQueues", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 61, + "src": "14360:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_$", + "typeString": "mapping(bytes32 => struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref)" + } + }, + "id": 401, + "indexExpression": + { + "expression": + { + "id": 399, + "name": "warpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 275, + "src": "14374:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage memory" + } + }, + "id": 400, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14386:13:4", + "memberName": "sourceChainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1338, + "src": "14374:25:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14360:40:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref" + } + }, + "id": 402, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14401:7:4", + "memberName": "enqueue", + "nodeType": "MemberAccess", + "referencedDeclaration": 1708, + "src": "14360:48:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$returns$__$attached_to$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$", + "typeString": "function (struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer,struct TeleporterMessageReceipt memory)" + } + }, + "id": 408, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "14360:242:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 409, + "nodeType": "ExpressionStatement", + "src": "14360:242:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 411, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 324, + "src": "14656:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 412, + "name": "warpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 275, + "src": "14679:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage memory" + } + }, + "id": 413, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14691:13:4", + "memberName": "sourceChainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1338, + "src": "14679:25:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 414, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "14718:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 415, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14722:6:4", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "14718:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 416, + "name": "relayerRewardAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 268, + "src": "14742:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 417, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "14776:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + ], + "id": 410, + "name": "ReceiveCrossChainMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1494, + "src": "14618:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_address_$_t_struct$_TeleporterMessage_$1431_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,address,address,struct TeleporterMessage memory)" + } + }, + "id": 418, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "14618:185:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 419, + "nodeType": "EmitStatement", + "src": "14613:190:4" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 424, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "id": 420, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "14850:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 421, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14868:7:4", + "memberName": "message", + "nodeType": "MemberAccess", + "referencedDeclaration": 1430, + "src": "14850:25:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 422, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14876:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "14850:32:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 423, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14885:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "14850:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 433, + "nodeType": "IfStatement", + "src": "14846:154:4", + "trueBody": + { + "id": 432, + "nodeType": "Block", + "src": "14888:112:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 426, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 324, + "src": "14933:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 427, + "name": "warpMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 275, + "src": "14944:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_WarpMessage_$1343_memory_ptr", + "typeString": "struct WarpMessage memory" + } + }, + "id": 428, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "14956:13:4", + "memberName": "sourceChainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1338, + "src": "14944:25:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 429, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 301, + "src": "14971:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + ], + "id": 425, + "name": "_handleInitialMessageExecution", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1271, + "src": "14902:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_struct$_TeleporterMessage_$1431_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,struct TeleporterMessage memory)" + } + }, + "id": 430, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "14902:87:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 431, + "nodeType": "ExpressionStatement", + "src": "14902:87:4" + } + ] + } + } + ] + }, + "documentation": + { + "id": 264, + "nodeType": "StructuredDocumentation", + "src": "10586:782:4", + "text": " @dev Emits a {ReceiveCrossChainMessage} event.\n Re-entrancy is explicitly disallowed between receiving functions. One message is not able to receive another message.\n Requirements:\n - `relayerRewardAddress` must not be the zero address.\n - `messageIndex` must specify a valid warp message in the transaction's storage slots.\n - Valid warp message provided in storage slots, and sender address matches the address of this contract.\n - Teleporter message `destinationBlockchainID` must match the `blockchainID` of this contract.\n - Teleporter message was not previously received.\n - Transaction was sent by an allowed relayer for corresponding teleporter message.\n @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "ccb5f809", + "id": 435, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "id": 271, + "kind": "modifierInvocation", + "modifierName": + { + "id": 270, + "name": "receiverNonReentrant", + "nameLocations": + [ + "11489:20:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1921, + "src": "11489:20:4" + }, + "nodeType": "ModifierInvocation", + "src": "11489:20:4" + } + ], + "name": "receiveCrossChainMessage", + "nameLocation": "11382:24:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 269, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 266, + "mutability": "mutable", + "name": "messageIndex", + "nameLocation": "11423:12:4", + "nodeType": "VariableDeclaration", + "scope": 435, + "src": "11416:19:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": + { + "id": 265, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "11416:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 268, + "mutability": "mutable", + "name": "relayerRewardAddress", + "nameLocation": "11453:20:4", + "nodeType": "VariableDeclaration", + "scope": 435, + "src": "11445:28:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 267, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "11445:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "11406:73:4" + }, + "returnParameters": + { + "id": 272, + "nodeType": "ParameterList", + "parameters": [], + "src": "11510:0:4" + }, + "scope": 1334, + "src": "11373:3633:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1558 + ], + "body": + { + "id": 532, + "nodeType": "Block", + "src": "15984:2860:4", + "statements": + [ + { + "assignments": + [ + 447 + ], + "declarations": + [ + { + "constant": false, + "id": 447, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "16351:9:4", + "nodeType": "VariableDeclaration", + "scope": 532, + "src": "16343:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 446, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16343:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 454, + "initialValue": + { + "arguments": + [ + { + "id": 449, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 438, + "src": "16394:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 450, + "name": "blockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 52, + "src": "16414:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 451, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 441, + "src": "16428:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 452, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "16436:12:4", + "memberName": "messageNonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 1413, + "src": "16428:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 448, + "name": "calculateMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 928, + "src": "16375:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32,uint256) view returns (bytes32)" + } + }, + "id": 453, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "16375:74:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "16343:106:4" + }, + { + "assignments": + [ + 456 + ], + "declarations": + [ + { + "constant": false, + "id": 456, + "mutability": "mutable", + "name": "failedMessageHash", + "nameLocation": "16590:17:4", + "nodeType": "VariableDeclaration", + "scope": 532, + "src": "16582:25:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 455, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16582:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 460, + "initialValue": + { + "baseExpression": + { + "id": 457, + "name": "receivedFailedMessageHashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 72, + "src": "16610:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bytes32_$", + "typeString": "mapping(bytes32 => bytes32)" + } + }, + "id": 459, + "indexExpression": + { + "id": 458, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 447, + "src": "16638:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "16610:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "16582:66:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 467, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 462, + "name": "failedMessageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 456, + "src": "16666:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 465, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16695:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 464, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "16687:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": + { + "id": 463, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "16687:7:4", + "typeDescriptions": {} + } + }, + "id": 466, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "16687:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "16666:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a206d657373616765206e6f7420666f756e64", + "id": 468, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16699:40:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_199fbf667868513fdcfeb4133baa4bac2a64719285610cf7dd50a36abe28043a", + "typeString": "literal_string \"TeleporterMessenger: message not found\"" + }, + "value": "TeleporterMessenger: message not found" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_199fbf667868513fdcfeb4133baa4bac2a64719285610cf7dd50a36abe28043a", + "typeString": "literal_string \"TeleporterMessenger: message not found\"" + } + ], + "id": 461, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "16658:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 469, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "16658:82:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 470, + "nodeType": "ExpressionStatement", + "src": "16658:82:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 479, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 475, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 441, + "src": "16792:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + ], + "expression": + { + "id": 473, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "16781:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 474, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "16785:6:4", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "16781:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 476, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "16781:19:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 472, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "16771:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 477, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "16771:30:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "id": 478, + "name": "failedMessageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 456, + "src": "16805:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "16771:51:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20696e76616c6964206d6573736167652068617368", + "id": 480, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16836:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_26676139843dc31081160e94c107767332aeb22512cc2cec1c0677f4002ae00b", + "typeString": "literal_string \"TeleporterMessenger: invalid message hash\"" + }, + "value": "TeleporterMessenger: invalid message hash" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_26676139843dc31081160e94c107767332aeb22512cc2cec1c0677f4002ae00b", + "typeString": "literal_string \"TeleporterMessenger: invalid message hash\"" + } + ], + "id": 471, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "16750:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 481, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "16750:139:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 482, + "nodeType": "ExpressionStatement", + "src": "16750:139:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 489, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "expression": + { + "id": 484, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 441, + "src": "17107:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 485, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "17115:18:4", + "memberName": "destinationAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1419, + "src": "17107:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 486, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "17134:4:4", + "memberName": "code", + "nodeType": "MemberAccess", + "src": "17107:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 487, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "17139:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "17107:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 488, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17148:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "17107:42:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a2064657374696e6174696f6e206164647265737320686173206e6f20636f6465", + "id": 490, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17163:54:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_794b15fe49c19a1ab829403e5a9dff963f7ebee8d665d2934810f35781bd7a56", + "typeString": "literal_string \"TeleporterMessenger: destination address has no code\"" + }, + "value": "TeleporterMessenger: destination address has no code" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_794b15fe49c19a1ab829403e5a9dff963f7ebee8d665d2934810f35781bd7a56", + "typeString": "literal_string \"TeleporterMessenger: destination address has no code\"" + } + ], + "id": 483, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "17086:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 491, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "17086:141:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 492, + "nodeType": "ExpressionStatement", + "src": "17086:141:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 494, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 447, + "src": "17432:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 495, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 438, + "src": "17443:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 493, + "name": "MessageExecuted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1480, + "src": "17416:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32)" + } + }, + "id": 496, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "17416:46:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 497, + "nodeType": "EmitStatement", + "src": "17411:51:4" + }, + { + "expression": + { + "id": 501, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "17472:45:4", + "subExpression": + { + "baseExpression": + { + "id": 498, + "name": "receivedFailedMessageHashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 72, + "src": "17479:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bytes32_$", + "typeString": "mapping(bytes32 => bytes32)" + } + }, + "id": 500, + "indexExpression": + { + "id": 499, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 447, + "src": "17507:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "17479:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 502, + "nodeType": "ExpressionStatement", + "src": "17472:45:4" + }, + { + "assignments": + [ + 504 + ], + "declarations": + [ + { + "constant": false, + "id": 504, + "mutability": "mutable", + "name": "payload", + "nameLocation": "17886:7:4", + "nodeType": "VariableDeclaration", + "scope": 532, + "src": "17873:20:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 503, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "17873:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 516, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 507, + "name": "ITeleporterReceiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1667, + "src": "17924:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_ITeleporterReceiver_$1667_$", + "typeString": "type(contract ITeleporterReceiver)" + } + }, + "id": 508, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "17944:24:4", + "memberName": "receiveTeleporterMessage", + "nodeType": "MemberAccess", + "referencedDeclaration": 1666, + "src": "17924:44:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_declaration_nonpayable$_t_bytes32_$_t_address_$_t_bytes_calldata_ptr_$returns$__$", + "typeString": "function ITeleporterReceiver.receiveTeleporterMessage(bytes32,address,bytes calldata)" + } + }, + { + "components": + [ + { + "id": 509, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 438, + "src": "17983:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 510, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 441, + "src": "18003:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 511, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "18011:19:4", + "memberName": "originSenderAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1415, + "src": "18003:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 512, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 441, + "src": "18032:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 513, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "18040:7:4", + "memberName": "message", + "nodeType": "MemberAccess", + "referencedDeclaration": 1430, + "src": "18032:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "id": 514, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "17982:66:4", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$_t_bytes_calldata_ptr_$", + "typeString": "tuple(bytes32,address,bytes calldata)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_function_declaration_nonpayable$_t_bytes32_$_t_address_$_t_bytes_calldata_ptr_$returns$__$", + "typeString": "function ITeleporterReceiver.receiveTeleporterMessage(bytes32,address,bytes calldata)" + }, + { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$_t_bytes_calldata_ptr_$", + "typeString": "tuple(bytes32,address,bytes calldata)" + } + ], + "expression": + { + "id": 505, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "17896:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 506, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "17900:10:4", + "memberName": "encodeCall", + "nodeType": "MemberAccess", + "src": "17896:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencodecall_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 515, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "17896:162:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "17873:185:4" + }, + { + "assignments": + [ + 518 + ], + "declarations": + [ + { + "constant": false, + "id": 518, + "mutability": "mutable", + "name": "success", + "nameLocation": "18688:7:4", + "nodeType": "VariableDeclaration", + "scope": 532, + "src": "18683:12:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 517, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "18683:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 526, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 520, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 441, + "src": "18717:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage calldata" + } + }, + "id": 521, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "18725:18:4", + "memberName": "destinationAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1419, + "src": "18717:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 522, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -7, + "src": "18745:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 523, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "18745:9:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 524, + "name": "payload", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 504, + "src": "18756:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 519, + "name": "_tryExecuteMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1289, + "src": "18698:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bool_$", + "typeString": "function (address,uint256,bytes memory) returns (bool)" + } + }, + "id": 525, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "18698:66:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "18683:81:4" + }, + { + "expression": + { + "arguments": + [ + { + "id": 528, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 518, + "src": "18782:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20726574727920657865637574696f6e206661696c6564", + "id": 529, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18791:45:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_27552fec1126874442346941805be6fbd62bf2eb60c636ec6c90ddb730e79927", + "typeString": "literal_string \"TeleporterMessenger: retry execution failed\"" + }, + "value": "TeleporterMessenger: retry execution failed" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_27552fec1126874442346941805be6fbd62bf2eb60c636ec6c90ddb730e79927", + "typeString": "literal_string \"TeleporterMessenger: retry execution failed\"" + } + ], + "id": 527, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "18774:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 530, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "18774:63:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 531, + "nodeType": "ExpressionStatement", + "src": "18774:63:4" + } + ] + }, + "documentation": + { + "id": 436, + "nodeType": "StructuredDocumentation", + "src": "15012:820:4", + "text": " @dev A Teleporter message has an associated `requiredGasLimit` that is used to execute the message.\n If the `requiredGasLimit` is too low, then the message execution will fail. This method allows\n for retrying the execution of a message with a higher gas limit. Contrary to `receiveCrossChainMessage`,\n which will only use `requiredGasLimit` in the sub-call to execute the message, this method may\n use all of the gas available in the transaction.\n Reverts if the message execution fails again on the specified message.\n Emits a {MessageExecuted} event if the retry is successful.\n Requirements:\n - `message` must have previously failed to execute, and matches the hash of the failed message.\n @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "fc2d6197", + "id": 533, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "id": 444, + "kind": "modifierInvocation", + "modifierName": + { + "id": 443, + "name": "receiverNonReentrant", + "nameLocations": + [ + "15963:20:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1921, + "src": "15963:20:4" + }, + "nodeType": "ModifierInvocation", + "src": "15963:20:4" + } + ], + "name": "retryMessageExecution", + "nameLocation": "15846:21:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 442, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 438, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "15885:18:4", + "nodeType": "VariableDeclaration", + "scope": 533, + "src": "15877:26:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 437, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "15877:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 441, + "mutability": "mutable", + "name": "message", + "nameLocation": "15940:7:4", + "nodeType": "VariableDeclaration", + "scope": 533, + "src": "15913:34:4", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_calldata_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 440, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 439, + "name": "TeleporterMessage", + "nameLocations": + [ + "15913:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "15913:17:4" + }, + "referencedDeclaration": 1431, + "src": "15913:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "15867:86:4" + }, + "returnParameters": + { + "id": 445, + "nodeType": "ParameterList", + "parameters": [], + "src": "15984:0:4" + }, + "scope": 1334, + "src": "15837:3007:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1575 + ], + "body": + { + "id": 651, + "nodeType": "Block", + "src": "20109:2013:4", + "statements": + [ + { + "assignments": + [ + 553 + ], + "declarations": + [ + { + "constant": false, + "id": 553, + "mutability": "mutable", + "name": "blockchainID_", + "nameLocation": "20377:13:4", + "nodeType": "VariableDeclaration", + "scope": 651, + "src": "20369:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 552, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "20369:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 555, + "initialValue": + { + "id": 554, + "name": "blockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 52, + "src": "20393:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "20369:36:4" + }, + { + "assignments": + [ + 560 + ], + "declarations": + [ + { + "constant": false, + "id": 560, + "mutability": "mutable", + "name": "receiptsToSend", + "nameLocation": "20548:14:4", + "nodeType": "VariableDeclaration", + "scope": 651, + "src": "20514:48:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + }, + "typeName": + { + "baseType": + { + "id": 558, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 557, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "20514:24:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "20514:24:4" + }, + "referencedDeclaration": 1396, + "src": "20514:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 559, + "nodeType": "ArrayTypeName", + "src": "20514:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + }, + "visibility": "internal" + } + ], + "id": 568, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 565, + "name": "messageIDs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 539, + "src": "20608:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_calldata_ptr", + "typeString": "bytes32[] calldata" + } + }, + "id": 566, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "20619:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "20608:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 564, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "20577:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr_$", + "typeString": "function (uint256) pure returns (struct TeleporterMessageReceipt memory[] memory)" + }, + "typeName": + { + "baseType": + { + "id": 562, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 561, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "20581:24:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "20581:24:4" + }, + "referencedDeclaration": 1396, + "src": "20581:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 563, + "nodeType": "ArrayTypeName", + "src": "20581:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + } + }, + "id": 567, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "20577:49:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "20514:112:4" + }, + { + "assignments": + [ + 570 + ], + "declarations": + [ + { + "constant": false, + "id": 570, + "mutability": "mutable", + "name": "length", + "nameLocation": "20644:6:4", + "nodeType": "VariableDeclaration", + "scope": 651, + "src": "20636:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 569, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20636:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 573, + "initialValue": + { + "expression": + { + "id": 571, + "name": "messageIDs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 539, + "src": "20653:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_calldata_ptr", + "typeString": "bytes32[] calldata" + } + }, + "id": 572, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "20664:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "20653:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "20636:34:4" + }, + { + "body": + { + "id": 628, + "nodeType": "Block", + "src": "20713:979:4", + "statements": + [ + { + "assignments": + [ + 584 + ], + "declarations": + [ + { + "constant": false, + "id": 584, + "mutability": "mutable", + "name": "receivedMessageID", + "nameLocation": "20735:17:4", + "nodeType": "VariableDeclaration", + "scope": 628, + "src": "20727:25:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 583, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "20727:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 588, + "initialValue": + { + "baseExpression": + { + "id": 585, + "name": "messageIDs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 539, + "src": "20755:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_calldata_ptr", + "typeString": "bytes32[] calldata" + } + }, + "id": 587, + "indexExpression": + { + "id": 586, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 575, + "src": "20766:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "20755:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "20727:41:4" + }, + { + "assignments": + [ + 590 + ], + "declarations": + [ + { + "constant": false, + "id": 590, + "mutability": "mutable", + "name": "receivedMessageNonce", + "nameLocation": "20841:20:4", + "nodeType": "VariableDeclaration", + "scope": 628, + "src": "20833:28:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 589, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20833:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 594, + "initialValue": + { + "baseExpression": + { + "id": 591, + "name": "_receivedMessageNonces", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 77, + "src": "20864:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_uint256_$", + "typeString": "mapping(bytes32 => uint256)" + } + }, + "id": 593, + "indexExpression": + { + "id": 592, + "name": "receivedMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 584, + "src": "20887:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "20864:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "20833:72:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 598, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 596, + "name": "receivedMessageNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 590, + "src": "20927:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "hexValue": "30", + "id": 597, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20951:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "20927:25:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a2072656365697074206e6f7420666f756e64", + "id": 599, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20954:40:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_10effb497fc7b60f5b99896a757a8286a3dbcb42b115165ba78522fc91964696", + "typeString": "literal_string \"TeleporterMessenger: receipt not found\"" + }, + "value": "TeleporterMessenger: receipt not found" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_10effb497fc7b60f5b99896a757a8286a3dbcb42b115165ba78522fc91964696", + "typeString": "literal_string \"TeleporterMessenger: receipt not found\"" + } + ], + "id": 595, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "20919:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 600, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "20919:76:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 601, + "nodeType": "ExpressionStatement", + "src": "20919:76:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 609, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 603, + "name": "receivedMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 584, + "src": "21127:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "arguments": + [ + { + "id": 605, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 536, + "src": "21187:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 606, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 553, + "src": "21207:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 607, + "name": "receivedMessageNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 590, + "src": "21222:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 604, + "name": "calculateMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 928, + "src": "21168:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32,uint256) view returns (bytes32)" + } + }, + "id": 608, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "21168:75:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "21127:116:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a206d657373616765204944206e6f742066726f6d20736f7572636520626c6f636b636861696e", + "id": 610, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21261:60:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_e4eef1803bde8b064647ccd003307f8902b22c94171d8be9ff7c90f918c19fdd", + "typeString": "literal_string \"TeleporterMessenger: message ID not from source blockchain\"" + }, + "value": "TeleporterMessenger: message ID not from source blockchain" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e4eef1803bde8b064647ccd003307f8902b22c94171d8be9ff7c90f918c19fdd", + "typeString": "literal_string \"TeleporterMessenger: message ID not from source blockchain\"" + } + ], + "id": 602, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "21102:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 611, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "21102:233:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 612, + "nodeType": "ExpressionStatement", + "src": "21102:233:4" + }, + { + "assignments": + [ + 614 + ], + "declarations": + [ + { + "constant": false, + "id": 614, + "mutability": "mutable", + "name": "relayerRewardAddress", + "nameLocation": "21421:20:4", + "nodeType": "VariableDeclaration", + "scope": 628, + "src": "21413:28:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 613, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "21413:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 618, + "initialValue": + { + "baseExpression": + { + "id": 615, + "name": "_relayerRewardAddresses", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 82, + "src": "21444:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_address_$", + "typeString": "mapping(bytes32 => address)" + } + }, + "id": 617, + "indexExpression": + { + "id": 616, + "name": "receivedMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 584, + "src": "21468:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21444:42:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "21413:73:4" + }, + { + "expression": + { + "id": 626, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "id": 619, + "name": "receiptsToSend", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 560, + "src": "21501:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + "id": 621, + "indexExpression": + { + "id": 620, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 575, + "src": "21516:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "21501:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "arguments": + [ + { + "id": 623, + "name": "receivedMessageNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 590, + "src": "21586:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 624, + "name": "relayerRewardAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 614, + "src": "21646:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 622, + "name": "TeleporterMessageReceipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1396, + "src": "21521:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_TeleporterMessageReceipt_$1396_storage_ptr_$", + "typeString": "type(struct TeleporterMessageReceipt storage pointer)" + } + }, + "id": 625, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "nameLocations": + [ + "21564:20:4", + "21624:20:4" + ], + "names": + [ + "receivedMessageNonce", + "relayerRewardAddress" + ], + "nodeType": "FunctionCall", + "src": "21521:160:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "src": "21501:180:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "id": 627, + "nodeType": "ExpressionStatement", + "src": "21501:180:4" + } + ] + }, + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 579, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 577, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 575, + "src": "20696:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 578, + "name": "length", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 570, + "src": "20700:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "20696:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 629, + "initializationExpression": + { + "assignments": + [ + 575 + ], + "declarations": + [ + { + "constant": false, + "id": 575, + "mutability": "mutable", + "name": "i", + "nameLocation": "20693:1:4", + "nodeType": "VariableDeclaration", + "scope": 629, + "src": "20685:9:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 574, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20685:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 576, + "nodeType": "VariableDeclarationStatement", + "src": "20685:9:4" + }, + "isSimpleCounterLoop": true, + "loopExpression": + { + "expression": + { + "id": 581, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": true, + "src": "20708:3:4", + "subExpression": + { + "id": 580, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 575, + "src": "20710:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 582, + "nodeType": "ExpressionStatement", + "src": "20708:3:4" + }, + "nodeType": "ForStatement", + "src": "20680:1012:4" + }, + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 632, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 536, + "src": "21811:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": + [ + { + "hexValue": "30", + "id": 635, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21875:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 634, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21867:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 633, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "21867:7:4", + "typeDescriptions": {} + } + }, + "id": 636, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "21867:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 637, + "name": "feeInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 542, + "src": "21904:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_calldata_ptr", + "typeString": "struct TeleporterFeeInfo calldata" + } + }, + { + "arguments": + [ + { + "hexValue": "30", + "id": 640, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21955:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 639, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21947:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": + { + "id": 638, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "21947:7:4", + "typeDescriptions": {} + } + }, + "id": 641, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "21947:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 642, + "name": "allowedRelayerAddresses", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 545, + "src": "22000:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_calldata_ptr", + "typeString": "address[] calldata" + } + }, + { + "arguments": + [ + { + "hexValue": "30", + "id": 645, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22060:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 644, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "22050:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$", + "typeString": "function (uint256) pure returns (bytes memory)" + }, + "typeName": + { + "id": 643, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "22054:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + } + }, + "id": 646, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "22050:12:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_calldata_ptr", + "typeString": "struct TeleporterFeeInfo calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_array$_t_address_$dyn_calldata_ptr", + "typeString": "address[] calldata" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 631, + "name": "TeleporterMessageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1411, + "src": "21745:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_TeleporterMessageInput_$1411_storage_ptr_$", + "typeString": "type(struct TeleporterMessageInput storage pointer)" + } + }, + "id": 647, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "nameLocations": + [ + "21786:23:4", + "21847:18:4", + "21895:7:4", + "21929:16:4", + "21975:23:4", + "22041:7:4" + ], + "names": + [ + "destinationBlockchainID", + "destinationAddress", + "feeInfo", + "requiredGasLimit", + "allowedRelayerAddresses", + "message" + ], + "nodeType": "FunctionCall", + "src": "21745:332:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + { + "id": 648, + "name": "receiptsToSend", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 560, + "src": "22091:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + }, + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + ], + "id": 630, + "name": "_sendTeleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1108, + "src": "21709:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_struct$_TeleporterMessageInput_$1411_memory_ptr_$_t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (struct TeleporterMessageInput memory,struct TeleporterMessageReceipt memory[] memory) returns (bytes32)" + } + }, + "id": 649, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "21709:406:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 551, + "id": 650, + "nodeType": "Return", + "src": "21702:413:4" + } + ] + }, + "documentation": + { + "id": 534, + "nodeType": "StructuredDocumentation", + "src": "18850:1000:4", + "text": " @dev There is no explicit limit to the number of receipts able to be sent by a {sendSpecifiedReceipts} message because\n this method is intended to be used by relayers themselves to ensure their receipts get returned.\n There is no fee associated with the empty message, and the same relayer is expected to relay it\n themselves in order to claim their rewards, so it is their responsibility to ensure that the necessary\n gas is provided for however many receipts are being retried.\n These specified receipts are not removed from their corresponding receipt queue because there\n is no efficient way to remove a specific receipt from an arbitrary position in the queue, and it is\n harmless for receipts to be sent multiple times within the protocol.\n Emits {SendCrossChainMessage} event.\n Requirements:\n - `messageIDs` must all be valid and have existing receipts.\n @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "a9a85614", + "id": 652, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "id": 548, + "kind": "modifierInvocation", + "modifierName": + { + "id": 547, + "name": "senderNonReentrant", + "nameLocations": + [ + "20072:18:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1902, + "src": "20072:18:4" + }, + "nodeType": "ModifierInvocation", + "src": "20072:18:4" + } + ], + "name": "sendSpecifiedReceipts", + "nameLocation": "19864:21:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 546, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 536, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "19903:18:4", + "nodeType": "VariableDeclaration", + "scope": 652, + "src": "19895:26:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 535, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19895:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 539, + "mutability": "mutable", + "name": "messageIDs", + "nameLocation": "19950:10:4", + "nodeType": "VariableDeclaration", + "scope": 652, + "src": "19931:29:4", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_calldata_ptr", + "typeString": "bytes32[]" + }, + "typeName": + { + "baseType": + { + "id": 537, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "19931:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 538, + "nodeType": "ArrayTypeName", + "src": "19931:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 542, + "mutability": "mutable", + "name": "feeInfo", + "nameLocation": "19997:7:4", + "nodeType": "VariableDeclaration", + "scope": 652, + "src": "19970:34:4", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_calldata_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 541, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 540, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "19970:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "19970:17:4" + }, + "referencedDeclaration": 1436, + "src": "19970:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 545, + "mutability": "mutable", + "name": "allowedRelayerAddresses", + "nameLocation": "20033:23:4", + "nodeType": "VariableDeclaration", + "scope": 652, + "src": "20014:42:4", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_calldata_ptr", + "typeString": "address[]" + }, + "typeName": + { + "baseType": + { + "id": 543, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "20014:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 544, + "nodeType": "ArrayTypeName", + "src": "20014:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + } + ], + "src": "19885:177:4" + }, + "returnParameters": + { + "id": 551, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 550, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 652, + "src": "20100:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 549, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "20100:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "20099:9:4" + }, + "scope": 1334, + "src": "19855:2267:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1581 + ], + "body": + { + "id": 698, + "nodeType": "Block", + "src": "22337:734:4", + "statements": + [ + { + "assignments": + [ + 659 + ], + "declarations": + [ + { + "constant": false, + "id": 659, + "mutability": "mutable", + "name": "rewardAmount", + "nameLocation": "22355:12:4", + "nodeType": "VariableDeclaration", + "scope": 698, + "src": "22347:20:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 658, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "22347:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 666, + "initialValue": + { + "baseExpression": + { + "baseExpression": + { + "id": 660, + "name": "_relayerRewardAmounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 89, + "src": "22370:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 663, + "indexExpression": + { + "expression": + { + "id": 661, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "22392:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 662, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "22396:6:4", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "22392:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22370:33:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 665, + "indexExpression": + { + "id": 664, + "name": "feeAsset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 655, + "src": "22404:8:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22370:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "22347:66:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 670, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 668, + "name": "rewardAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 659, + "src": "22431:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 669, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22446:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "22431:16:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a206e6f2072657761726420746f2072656465656d", + "id": 671, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22449:42:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_162e06aabf58a41b1cbea9057268a26e43a89b2e7c54e3afe46f30a9bb18bc42", + "typeString": "literal_string \"TeleporterMessenger: no reward to redeem\"" + }, + "value": "TeleporterMessenger: no reward to redeem" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_162e06aabf58a41b1cbea9057268a26e43a89b2e7c54e3afe46f30a9bb18bc42", + "typeString": "literal_string \"TeleporterMessenger: no reward to redeem\"" + } + ], + "id": 667, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "22423:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 672, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "22423:69:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 673, + "nodeType": "ExpressionStatement", + "src": "22423:69:4" + }, + { + "expression": + { + "id": 680, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "22643:50:4", + "subExpression": + { + "baseExpression": + { + "baseExpression": + { + "id": 674, + "name": "_relayerRewardAmounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 89, + "src": "22650:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 677, + "indexExpression": + { + "expression": + { + "id": 675, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "22672:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 676, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "22676:6:4", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "22672:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22650:33:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 679, + "indexExpression": + { + "id": 678, + "name": "feeAsset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 655, + "src": "22684:8:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "22650:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 681, + "nodeType": "ExpressionStatement", + "src": "22643:50:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "expression": + { + "id": 683, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "22732:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 684, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "22736:6:4", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "22732:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 685, + "name": "feeAsset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 655, + "src": "22744:8:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 686, + "name": "rewardAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 659, + "src": "22754:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 682, + "name": "RelayerRewardsRedeemed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1515, + "src": "22709:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 687, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "22709:58:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 688, + "nodeType": "EmitStatement", + "src": "22704:63:4" + }, + { + "expression": + { + "arguments": + [ + { + "expression": + { + "id": 693, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "23039:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 694, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "23043:6:4", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "23039:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 695, + "name": "rewardAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 659, + "src": "23051:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": + { + "arguments": + [ + { + "id": 690, + "name": "feeAsset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 655, + "src": "23016:8:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 689, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2099, + "src": "23009:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_IERC20_$2099_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 691, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "23009:16:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 692, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "23026:12:4", + "memberName": "safeTransfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 2149, + "src": "23009:29:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_address_$_t_uint256_$returns$__$attached_to$_t_contract$_IERC20_$2099_$", + "typeString": "function (contract IERC20,address,uint256)" + } + }, + "id": 696, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "23009:55:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 697, + "nodeType": "ExpressionStatement", + "src": "23009:55:4" + } + ] + }, + "documentation": + { + "id": 653, + "nodeType": "StructuredDocumentation", + "src": "22128:133:4", + "text": " @dev Requirements:\n - `rewardAmount` must be non-zero.\n @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "22296c3a", + "id": 699, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "redeemRelayerRewards", + "nameLocation": "22275:20:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 656, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 655, + "mutability": "mutable", + "name": "feeAsset", + "nameLocation": "22313:8:4", + "nodeType": "VariableDeclaration", + "scope": 699, + "src": "22305:16:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 654, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22305:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "22295:32:4" + }, + "returnParameters": + { + "id": 657, + "nodeType": "ParameterList", + "parameters": [], + "src": "22337:0:4" + }, + "scope": 1334, + "src": "22266:805:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1589 + ], + "body": + { + "id": 712, + "nodeType": "Block", + "src": "23222:62:4", + "statements": + [ + { + "expression": + { + "expression": + { + "baseExpression": + { + "id": 707, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "23239:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 709, + "indexExpression": + { + "id": 708, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 702, + "src": "23255:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23239:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "id": 710, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "23266:11:4", + "memberName": "messageHash", + "nodeType": "MemberAccess", + "referencedDeclaration": 38, + "src": "23239:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 706, + "id": 711, + "nodeType": "Return", + "src": "23232:45:4" + } + ] + }, + "documentation": + { + "id": 700, + "nodeType": "StructuredDocumentation", + "src": "23077:51:4", + "text": " @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "399b77da", + "id": 713, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getMessageHash", + "nameLocation": "23142:14:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 703, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 702, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "23174:9:4", + "nodeType": "VariableDeclaration", + "scope": 713, + "src": "23166:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 701, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23166:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "23156:33:4" + }, + "returnParameters": + { + "id": 706, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 705, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 713, + "src": "23213:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 704, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23213:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "23212:9:4" + }, + "scope": 1334, + "src": "23133:151:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1597 + ], + "body": + { + "id": 725, + "nodeType": "Block", + "src": "23433:51:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 722, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 716, + "src": "23467:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 721, + "name": "_messageReceived", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1333, + "src": "23450:16:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (bytes32) view returns (bool)" + } + }, + "id": 723, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "23450:27:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 720, + "id": 724, + "nodeType": "Return", + "src": "23443:34:4" + } + ] + }, + "documentation": + { + "id": 714, + "nodeType": "StructuredDocumentation", + "src": "23290:51:4", + "text": " @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "ebc3b1ba", + "id": 726, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "messageReceived", + "nameLocation": "23355:15:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 717, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 716, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "23388:9:4", + "nodeType": "VariableDeclaration", + "scope": 726, + "src": "23380:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 715, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23380:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "23370:33:4" + }, + "returnParameters": + { + "id": 720, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 719, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 726, + "src": "23427:4:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 718, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "23427:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "23426:6:4" + }, + "scope": 1334, + "src": "23346:138:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1605 + ], + "body": + { + "id": 745, + "nodeType": "Block", + "src": "23644:149:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 736, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 729, + "src": "23679:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 735, + "name": "_messageReceived", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1333, + "src": "23662:16:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (bytes32) view returns (bool)" + } + }, + "id": 737, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "23662:27:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a206d657373616765206e6f74207265636569766564", + "id": 738, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23691:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_269e79d417cde7a543a622c00ca25bd512f3b2aff7b01471a003b9828048c618", + "typeString": "literal_string \"TeleporterMessenger: message not received\"" + }, + "value": "TeleporterMessenger: message not received" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_269e79d417cde7a543a622c00ca25bd512f3b2aff7b01471a003b9828048c618", + "typeString": "literal_string \"TeleporterMessenger: message not received\"" + } + ], + "id": 734, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "23654:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 739, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "23654:81:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 740, + "nodeType": "ExpressionStatement", + "src": "23654:81:4" + }, + { + "expression": + { + "baseExpression": + { + "id": 741, + "name": "_relayerRewardAddresses", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 82, + "src": "23752:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_address_$", + "typeString": "mapping(bytes32 => address)" + } + }, + "id": 743, + "indexExpression": + { + "id": 742, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 729, + "src": "23776:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23752:34:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "functionReturnParameters": 733, + "id": 744, + "nodeType": "Return", + "src": "23745:41:4" + } + ] + }, + "documentation": + { + "id": 727, + "nodeType": "StructuredDocumentation", + "src": "23490:51:4", + "text": " @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "2e27c223", + "id": 746, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getRelayerRewardAddress", + "nameLocation": "23555:23:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 730, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 729, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "23596:9:4", + "nodeType": "VariableDeclaration", + "scope": 746, + "src": "23588:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 728, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "23588:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "23578:33:4" + }, + "returnParameters": + { + "id": 733, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 732, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 746, + "src": "23635:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 731, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23635:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "23634:9:4" + }, + "scope": 1334, + "src": "23546:247:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1615 + ], + "body": + { + "id": 762, + "nodeType": "Block", + "src": "23978:64:4", + "statements": + [ + { + "expression": + { + "baseExpression": + { + "baseExpression": + { + "id": 756, + "name": "_relayerRewardAmounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 89, + "src": "23995:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 758, + "indexExpression": + { + "id": 757, + "name": "relayer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 749, + "src": "24017:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23995:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 760, + "indexExpression": + { + "id": 759, + "name": "feeAsset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 751, + "src": "24026:8:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23995:40:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 755, + "id": 761, + "nodeType": "Return", + "src": "23988:47:4" + } + ] + }, + "documentation": + { + "id": 747, + "nodeType": "StructuredDocumentation", + "src": "23799:51:4", + "text": " @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "c473eef8", + "id": 763, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "checkRelayerRewardAmount", + "nameLocation": "23864:24:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 752, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 749, + "mutability": "mutable", + "name": "relayer", + "nameLocation": "23906:7:4", + "nodeType": "VariableDeclaration", + "scope": 763, + "src": "23898:15:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 748, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23898:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 751, + "mutability": "mutable", + "name": "feeAsset", + "nameLocation": "23931:8:4", + "nodeType": "VariableDeclaration", + "scope": 763, + "src": "23923:16:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 750, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23923:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "23888:57:4" + }, + "returnParameters": + { + "id": 755, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 754, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 763, + "src": "23969:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 753, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "23969:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "23968:9:4" + }, + "scope": 1334, + "src": "23855:187:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1625 + ], + "body": + { + "id": 787, + "nodeType": "Block", + "src": "24198:144:4", + "statements": + [ + { + "assignments": + [ + 775 + ], + "declarations": + [ + { + "constant": false, + "id": 775, + "mutability": "mutable", + "name": "feeInfo", + "nameLocation": "24233:7:4", + "nodeType": "VariableDeclaration", + "scope": 787, + "src": "24208:32:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 774, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 773, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "24208:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "24208:17:4" + }, + "referencedDeclaration": 1436, + "src": "24208:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + } + ], + "id": 780, + "initialValue": + { + "expression": + { + "baseExpression": + { + "id": 776, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "24243:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 778, + "indexExpression": + { + "id": 777, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 766, + "src": "24259:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24243:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "id": 779, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "24270:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "24243:34:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage", + "typeString": "struct TeleporterFeeInfo storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "24208:69:4" + }, + { + "expression": + { + "components": + [ + { + "expression": + { + "id": 781, + "name": "feeInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 775, + "src": "24295:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 782, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "24303:15:4", + "memberName": "feeTokenAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1433, + "src": "24295:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 783, + "name": "feeInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 775, + "src": "24320:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 784, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "24328:6:4", + "memberName": "amount", + "nodeType": "MemberAccess", + "referencedDeclaration": 1435, + "src": "24320:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 785, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "24294:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_address_$_t_uint256_$", + "typeString": "tuple(address,uint256)" + } + }, + "functionReturnParameters": 772, + "id": 786, + "nodeType": "Return", + "src": "24287:48:4" + } + ] + }, + "documentation": + { + "id": 764, + "nodeType": "StructuredDocumentation", + "src": "24048:51:4", + "text": " @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "e69d606a", + "id": 788, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getFeeInfo", + "nameLocation": "24113:10:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 767, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 766, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "24141:9:4", + "nodeType": "VariableDeclaration", + "scope": 788, + "src": "24133:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 765, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "24133:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "24123:33:4" + }, + "returnParameters": + { + "id": 772, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 769, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 788, + "src": "24180:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 768, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "24180:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 771, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 788, + "src": "24189:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 770, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "24189:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "24179:18:4" + }, + "scope": 1334, + "src": "24104:238:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1633 + ], + "body": + { + "id": 822, + "nodeType": "Block", + "src": "24660:288:4", + "statements": + [ + { + "assignments": + [ + 797 + ], + "declarations": + [ + { + "constant": false, + "id": 797, + "mutability": "mutable", + "name": "blockchainID_", + "nameLocation": "24678:13:4", + "nodeType": "VariableDeclaration", + "scope": 822, + "src": "24670:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 796, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "24670:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 799, + "initialValue": + { + "id": 798, + "name": "blockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 52, + "src": "24694:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "24670:36:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 806, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 801, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 797, + "src": "24724:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 804, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24749:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 803, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24741:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": + { + "id": 802, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "24741:7:4", + "typeDescriptions": {} + } + }, + "id": 805, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "24741:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "24724:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a207a65726f20626c6f636b636861696e204944", + "id": 807, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24753:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_9f0aaacb3383932ce173f4d373e9594b92d3296c755fa2c39501db861c86c1a8", + "typeString": "literal_string \"TeleporterMessenger: zero blockchain ID\"" + }, + "value": "TeleporterMessenger: zero blockchain ID" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_9f0aaacb3383932ce173f4d373e9594b92d3296c755fa2c39501db861c86c1a8", + "typeString": "literal_string \"TeleporterMessenger: zero blockchain ID\"" + } + ], + "id": 800, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "24716:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 808, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "24716:79:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 809, + "nodeType": "ExpressionStatement", + "src": "24716:79:4" + }, + { + "assignments": + [ + 811 + ], + "declarations": + [ + { + "constant": false, + "id": 811, + "mutability": "mutable", + "name": "nextMessageNonce", + "nameLocation": "24813:16:4", + "nodeType": "VariableDeclaration", + "scope": 822, + "src": "24805:24:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 810, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "24805:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 815, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 814, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 812, + "name": "messageNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 55, + "src": "24832:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "hexValue": "31", + "id": 813, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24847:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "24832:16:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "24805:43:4" + }, + { + "expression": + { + "arguments": + [ + { + "id": 817, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 797, + "src": "24884:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 818, + "name": "destinationBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 791, + "src": "24899:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 819, + "name": "nextMessageNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 811, + "src": "24924:16:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 816, + "name": "calculateMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 928, + "src": "24865:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32,uint256) view returns (bytes32)" + } + }, + "id": 820, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "24865:76:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 795, + "id": 821, + "nodeType": "Return", + "src": "24858:83:4" + } + ] + }, + "documentation": + { + "id": 789, + "nodeType": "StructuredDocumentation", + "src": "24348:202:4", + "text": " @notice Gets the next message ID to be used for a message sent from the contract instance.\n @return The next message ID to be used for a message sent from the contract instance." + }, + "functionSelector": "df20e8bc", + "id": 823, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getNextMessageID", + "nameLocation": "24564:16:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 792, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 791, + "mutability": "mutable", + "name": "destinationBlockchainID", + "nameLocation": "24598:23:4", + "nodeType": "VariableDeclaration", + "scope": 823, + "src": "24590:31:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 790, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "24590:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "24580:47:4" + }, + "returnParameters": + { + "id": 795, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 794, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 823, + "src": "24651:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 793, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "24651:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "24650:9:4" + }, + "scope": 1334, + "src": "24555:393:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1641 + ], + "body": + { + "id": 837, + "nodeType": "Block", + "src": "25113:64:4", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "expression": + { + "baseExpression": + { + "id": 831, + "name": "receiptQueues", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 61, + "src": "25130:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_$", + "typeString": "mapping(bytes32 => struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref)" + } + }, + "id": 833, + "indexExpression": + { + "id": 832, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 826, + "src": "25144:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25130:33:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref" + } + }, + "id": 834, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "25164:4:4", + "memberName": "size", + "nodeType": "MemberAccess", + "referencedDeclaration": 1839, + "src": "25130:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$returns$_t_uint256_$attached_to$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$", + "typeString": "function (struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer) view returns (uint256)" + } + }, + "id": 835, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "25130:40:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 830, + "id": 836, + "nodeType": "Return", + "src": "25123:47:4" + } + ] + }, + "documentation": + { + "id": 824, + "nodeType": "StructuredDocumentation", + "src": "24954:51:4", + "text": " @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "2bc8b0bf", + "id": 838, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getReceiptQueueSize", + "nameLocation": "25019:19:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 827, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 826, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "25056:18:4", + "nodeType": "VariableDeclaration", + "scope": 838, + "src": "25048:26:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 825, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25048:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "25038:42:4" + }, + "returnParameters": + { + "id": 830, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 829, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 838, + "src": "25104:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 828, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25104:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "25103:9:4" + }, + "scope": 1334, + "src": "25010:167:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "baseFunctions": + [ + 1652 + ], + "body": + { + "id": 856, + "nodeType": "Block", + "src": "25387:82:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 853, + "name": "index", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 843, + "src": "25456:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": + { + "baseExpression": + { + "id": 849, + "name": "receiptQueues", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 61, + "src": "25404:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_$", + "typeString": "mapping(bytes32 => struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref)" + } + }, + "id": 851, + "indexExpression": + { + "id": 850, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 841, + "src": "25418:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25404:33:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceiptQueue_$1684_storage", + "typeString": "struct ReceiptQueue.TeleporterMessageReceiptQueue storage ref" + } + }, + "id": 852, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "25438:17:4", + "memberName": "getReceiptAtIndex", + "nodeType": "MemberAccess", + "referencedDeclaration": 1869, + "src": "25404:51:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$_t_uint256_$returns$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$attached_to$_t_struct$_TeleporterMessageReceiptQueue_$1684_storage_ptr_$", + "typeString": "function (struct ReceiptQueue.TeleporterMessageReceiptQueue storage pointer,uint256) view returns (struct TeleporterMessageReceipt memory)" + } + }, + "id": 854, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "25404:58:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "functionReturnParameters": 848, + "id": 855, + "nodeType": "Return", + "src": "25397:65:4" + } + ] + }, + "documentation": + { + "id": 839, + "nodeType": "StructuredDocumentation", + "src": "25183:51:4", + "text": " @inheritdoc ITeleporterMessenger" + }, + "functionSelector": "892bf412", + "id": 857, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getReceiptAtIndex", + "nameLocation": "25248:17:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 844, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 841, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "25283:18:4", + "nodeType": "VariableDeclaration", + "scope": 857, + "src": "25275:26:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 840, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25275:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 843, + "mutability": "mutable", + "name": "index", + "nameLocation": "25319:5:4", + "nodeType": "VariableDeclaration", + "scope": 857, + "src": "25311:13:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 842, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25311:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "25265:65:4" + }, + "returnParameters": + { + "id": 848, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 847, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 857, + "src": "25354:31:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt" + }, + "typeName": + { + "id": 846, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 845, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "25354:24:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "25354:24:4" + }, + "referencedDeclaration": 1396, + "src": "25354:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "visibility": "internal" + } + ], + "src": "25353:33:4" + }, + "scope": 1334, + "src": "25239:230:4", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "body": + { + "id": 901, + "nodeType": "Block", + "src": "25779:390:4", + "statements": + [ + { + "assignments": + [ + 864 + ], + "declarations": + [ + { + "constant": false, + "id": 864, + "mutability": "mutable", + "name": "blockchainID_", + "nameLocation": "25797:13:4", + "nodeType": "VariableDeclaration", + "scope": 901, + "src": "25789:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 863, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25789:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 866, + "initialValue": + { + "id": 865, + "name": "blockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 52, + "src": "25813:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "25789:36:4" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 872, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 867, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 864, + "src": "25839:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 870, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25864:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 869, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25856:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": + { + "id": 868, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25856:7:4", + "typeDescriptions": {} + } + }, + "id": 871, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "25856:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "25839:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 898, + "nodeType": "IfStatement", + "src": "25835:298:4", + "trueBody": + { + "id": 897, + "nodeType": "Block", + "src": "25868:265:4", + "statements": + [ + { + "expression": + { + "id": 877, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 873, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 864, + "src": "25882:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "expression": + { + "id": 874, + "name": "WARP_MESSENGER", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49, + "src": "25898:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IWarpMessenger_$1389", + "typeString": "contract IWarpMessenger" + } + }, + "id": 875, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "25913:15:4", + "memberName": "getBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1388, + "src": "25898:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$__$returns$_t_bytes32_$", + "typeString": "function () view external returns (bytes32)" + } + }, + "id": 876, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "25898:32:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "25882:48:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 878, + "nodeType": "ExpressionStatement", + "src": "25882:48:4" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 885, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 880, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 864, + "src": "25952:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 883, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25977:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 882, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25969:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": + { + "id": 881, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25969:7:4", + "typeDescriptions": {} + } + }, + "id": 884, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "25969:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "25952:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a207a65726f20626c6f636b636861696e204944", + "id": 886, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25981:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_9f0aaacb3383932ce173f4d373e9594b92d3296c755fa2c39501db861c86c1a8", + "typeString": "literal_string \"TeleporterMessenger: zero blockchain ID\"" + }, + "value": "TeleporterMessenger: zero blockchain ID" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_9f0aaacb3383932ce173f4d373e9594b92d3296c755fa2c39501db861c86c1a8", + "typeString": "literal_string \"TeleporterMessenger: zero blockchain ID\"" + } + ], + "id": 879, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "25944:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 887, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "25944:79:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 888, + "nodeType": "ExpressionStatement", + "src": "25944:79:4" + }, + { + "expression": + { + "id": 891, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 889, + "name": "blockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 52, + "src": "26037:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 890, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 864, + "src": "26052:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "26037:28:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 892, + "nodeType": "ExpressionStatement", + "src": "26037:28:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 894, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 864, + "src": "26108:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 893, + "name": "BlockchainIDInitialized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1442, + "src": "26084:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$returns$__$", + "typeString": "function (bytes32)" + } + }, + "id": 895, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "26084:38:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 896, + "nodeType": "EmitStatement", + "src": "26079:43:4" + } + ] + } + }, + { + "expression": + { + "id": 899, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 864, + "src": "26149:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 862, + "id": 900, + "nodeType": "Return", + "src": "26142:20:4" + } + ] + }, + "documentation": + { + "id": 858, + "nodeType": "StructuredDocumentation", + "src": "25475:240:4", + "text": " @notice If not already set, initializes blockchainID by getting the current\n blockchain ID value from the Warp precompile.\n @dev Emits {BlockchainIDInitialized} event.\n @return The current blockchain ID." + }, + "functionSelector": "0af5b4ff", + "id": 902, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "initializeBlockchainID", + "nameLocation": "25729:22:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 859, + "nodeType": "ParameterList", + "parameters": [], + "src": "25751:2:4" + }, + "returnParameters": + { + "id": 862, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 861, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 902, + "src": "25770:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 860, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "25770:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "25769:9:4" + }, + "scope": 1334, + "src": "25720:449:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": + { + "id": 927, + "nodeType": "Block", + "src": "26533:124:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "arguments": + [ + { + "id": 919, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "26591:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_TeleporterMessenger_$1334", + "typeString": "contract TeleporterMessenger" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_TeleporterMessenger_$1334", + "typeString": "contract TeleporterMessenger" + } + ], + "id": 918, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "26583:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 917, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "26583:7:4", + "typeDescriptions": {} + } + }, + "id": 920, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "26583:13:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 921, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 905, + "src": "26598:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 922, + "name": "destinationBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 907, + "src": "26618:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 923, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 909, + "src": "26643:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": + { + "id": 915, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "26572:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 916, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "26576:6:4", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "26572:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 924, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "26572:77:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 914, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "26562:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 925, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "26562:88:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 913, + "id": 926, + "nodeType": "Return", + "src": "26543:107:4" + } + ] + }, + "documentation": + { + "id": 903, + "nodeType": "StructuredDocumentation", + "src": "26175:189:4", + "text": " @notice Calculates the message ID for a message sent from this contract instance with the\n given source blockchain ID, destination blockchain ID, and message nonce." + }, + "functionSelector": "a8898181", + "id": 928, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "calculateMessageID", + "nameLocation": "26378:18:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 910, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 905, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "26414:18:4", + "nodeType": "VariableDeclaration", + "scope": 928, + "src": "26406:26:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 904, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26406:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 907, + "mutability": "mutable", + "name": "destinationBlockchainID", + "nameLocation": "26450:23:4", + "nodeType": "VariableDeclaration", + "scope": 928, + "src": "26442:31:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 906, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26442:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 909, + "mutability": "mutable", + "name": "nonce", + "nameLocation": "26491:5:4", + "nodeType": "VariableDeclaration", + "scope": 928, + "src": "26483:13:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 908, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26483:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "26396:106:4" + }, + "returnParameters": + { + "id": 913, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 912, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 928, + "src": "26524:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 911, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "26524:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "26523:9:4" + }, + "scope": 1334, + "src": "26369:288:4", + "stateMutability": "view", + "virtual": false, + "visibility": "public" + }, + { + "body": + { + "id": 974, + "nodeType": "Block", + "src": "26903:482:4", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 942, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 939, + "name": "allowedRelayers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 934, + "src": "27007:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 940, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "27023:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "27007:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 941, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27033:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "27007:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 946, + "nodeType": "IfStatement", + "src": "27003:69:4", + "trueBody": + { + "id": 945, + "nodeType": "Block", + "src": "27036:36:4", + "statements": + [ + { + "expression": + { + "hexValue": "74727565", + "id": 943, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27057:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 938, + "id": 944, + "nodeType": "Return", + "src": "27050:11:4" + } + ] + } + }, + { + "assignments": + [ + 948 + ], + "declarations": + [ + { + "constant": false, + "id": 948, + "mutability": "mutable", + "name": "length", + "nameLocation": "27171:6:4", + "nodeType": "VariableDeclaration", + "scope": 974, + "src": "27163:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 947, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27163:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 951, + "initialValue": + { + "expression": + { + "id": 949, + "name": "allowedRelayers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 934, + "src": "27180:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 950, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "27196:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "27180:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "27163:39:4" + }, + { + "body": + { + "id": 970, + "nodeType": "Block", + "src": "27245:112:4", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 965, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "baseExpression": + { + "id": 961, + "name": "allowedRelayers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 934, + "src": "27263:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 963, + "indexExpression": + { + "id": 962, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 953, + "src": "27279:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27263:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "id": 964, + "name": "delivererAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 931, + "src": "27285:16:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "27263:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 969, + "nodeType": "IfStatement", + "src": "27259:88:4", + "trueBody": + { + "id": 968, + "nodeType": "Block", + "src": "27303:44:4", + "statements": + [ + { + "expression": + { + "hexValue": "74727565", + "id": 966, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27328:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 938, + "id": 967, + "nodeType": "Return", + "src": "27321:11:4" + } + ] + } + } + ] + }, + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 957, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 955, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 953, + "src": "27228:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 956, + "name": "length", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 948, + "src": "27232:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27228:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 971, + "initializationExpression": + { + "assignments": + [ + 953 + ], + "declarations": + [ + { + "constant": false, + "id": 953, + "mutability": "mutable", + "name": "i", + "nameLocation": "27225:1:4", + "nodeType": "VariableDeclaration", + "scope": 971, + "src": "27217:9:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 952, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27217:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 954, + "nodeType": "VariableDeclarationStatement", + "src": "27217:9:4" + }, + "isSimpleCounterLoop": true, + "loopExpression": + { + "expression": + { + "id": 959, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": true, + "src": "27240:3:4", + "subExpression": + { + "id": 958, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 953, + "src": "27242:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 960, + "nodeType": "ExpressionStatement", + "src": "27240:3:4" + }, + "nodeType": "ForStatement", + "src": "27212:145:4" + }, + { + "expression": + { + "hexValue": "66616c7365", + "id": 972, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27373:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 938, + "id": 973, + "nodeType": "Return", + "src": "27366:12:4" + } + ] + }, + "documentation": + { + "id": 929, + "nodeType": "StructuredDocumentation", + "src": "26663:92:4", + "text": " @dev Checks whether `delivererAddress` is allowed to deliver the message." + }, + "id": 975, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_checkIsAllowedRelayer", + "nameLocation": "26769:22:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 935, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 931, + "mutability": "mutable", + "name": "delivererAddress", + "nameLocation": "26809:16:4", + "nodeType": "VariableDeclaration", + "scope": 975, + "src": "26801:24:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 930, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "26801:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 934, + "mutability": "mutable", + "name": "allowedRelayers", + "nameLocation": "26852:15:4", + "nodeType": "VariableDeclaration", + "scope": 975, + "src": "26835:32:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": + { + "baseType": + { + "id": 932, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "26835:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 933, + "nodeType": "ArrayTypeName", + "src": "26835:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "visibility": "internal" + } + ], + "src": "26791:82:4" + }, + "returnParameters": + { + "id": 938, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 937, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 975, + "src": "26897:4:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 936, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "26897:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "26896:6:4" + }, + "scope": 1334, + "src": "26760:625:4", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 1107, + "nodeType": "Block", + "src": "27842:2907:4", + "statements": + [ + { + "assignments": + [ + 989 + ], + "declarations": + [ + { + "constant": false, + "id": 989, + "mutability": "mutable", + "name": "blockchainID_", + "nameLocation": "27930:13:4", + "nodeType": "VariableDeclaration", + "scope": 1107, + "src": "27922:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 988, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "27922:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 992, + "initialValue": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 990, + "name": "initializeBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 902, + "src": "27946:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$_t_bytes32_$", + "typeString": "function () returns (bytes32)" + } + }, + "id": 991, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "27946:24:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "27922:48:4" + }, + { + "assignments": + [ + 994 + ], + "declarations": + [ + { + "constant": false, + "id": 994, + "mutability": "mutable", + "name": "messageNonce_", + "nameLocation": "28063:13:4", + "nodeType": "VariableDeclaration", + "scope": 1107, + "src": "28055:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 993, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "28055:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 997, + "initialValue": + { + "id": 996, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": true, + "src": "28079:14:4", + "subExpression": + { + "id": 995, + "name": "messageNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 55, + "src": "28081:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28055:38:4" + }, + { + "assignments": + [ + 999 + ], + "declarations": + [ + { + "constant": false, + "id": 999, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "28111:9:4", + "nodeType": "VariableDeclaration", + "scope": 1107, + "src": "28103:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 998, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "28103:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1006, + "initialValue": + { + "arguments": + [ + { + "id": 1001, + "name": "blockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 989, + "src": "28154:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 1002, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "28169:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1003, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "28182:23:4", + "memberName": "destinationBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1398, + "src": "28169:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1004, + "name": "messageNonce_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 994, + "src": "28207:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1000, + "name": "calculateMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 928, + "src": "28135:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32,uint256) view returns (bytes32)" + } + }, + "id": 1005, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "28135:86:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28103:118:4" + }, + { + "assignments": + [ + 1009 + ], + "declarations": + [ + { + "constant": false, + "id": 1009, + "mutability": "mutable", + "name": "teleporterMessage", + "nameLocation": "28305:17:4", + "nodeType": "VariableDeclaration", + "scope": 1107, + "src": "28280:42:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1008, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1007, + "name": "TeleporterMessage", + "nameLocations": + [ + "28280:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "28280:17:4" + }, + "referencedDeclaration": 1431, + "src": "28280:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "id": 1026, + "initialValue": + { + "arguments": + [ + { + "id": 1011, + "name": "messageNonce_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 994, + "src": "28371:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": + { + "id": 1012, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "28419:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 1013, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "28423:6:4", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "28419:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 1014, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "28468:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1015, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "28481:23:4", + "memberName": "destinationBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1398, + "src": "28468:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 1016, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "28538:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1017, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "28551:18:4", + "memberName": "destinationAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1400, + "src": "28538:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 1018, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "28601:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1019, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "28614:16:4", + "memberName": "requiredGasLimit", + "nodeType": "MemberAccess", + "referencedDeclaration": 1405, + "src": "28601:29:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": + { + "id": 1020, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "28669:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1021, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "28682:23:4", + "memberName": "allowedRelayerAddresses", + "nodeType": "MemberAccess", + "referencedDeclaration": 1408, + "src": "28669:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + { + "id": 1022, + "name": "receipts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 983, + "src": "28729:8:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + } + }, + { + "expression": + { + "id": 1023, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "28760:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1024, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "28773:7:4", + "memberName": "message", + "nodeType": "MemberAccess", + "referencedDeclaration": 1410, + "src": "28760:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + }, + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory[] memory" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1010, + "name": "TeleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1431, + "src": "28325:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_TeleporterMessage_$1431_storage_ptr_$", + "typeString": "type(struct TeleporterMessage storage pointer)" + } + }, + "id": 1025, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "nameLocations": + [ + "28357:12:4", + "28398:19:4", + "28443:23:4", + "28518:18:4", + "28583:16:4", + "28644:23:4", + "28719:8:4", + "28751:7:4" + ], + "names": + [ + "messageNonce", + "originSenderAddress", + "destinationBlockchainID", + "destinationAddress", + "requiredGasLimit", + "allowedRelayerAddresses", + "receipts", + "message" + ], + "nodeType": "FunctionCall", + "src": "28325:466:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28280:511:4" + }, + { + "assignments": + [ + 1028 + ], + "declarations": + [ + { + "constant": false, + "id": 1028, + "mutability": "mutable", + "name": "teleporterMessageBytes", + "nameLocation": "28814:22:4", + "nodeType": "VariableDeclaration", + "scope": 1107, + "src": "28801:35:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1027, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "28801:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 1033, + "initialValue": + { + "arguments": + [ + { + "id": 1031, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1009, + "src": "28850:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + ], + "expression": + { + "id": 1029, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "28839:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1030, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "28843:6:4", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "28839:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1032, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "28839:29:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "28801:67:4" + }, + { + "assignments": + [ + 1035 + ], + "declarations": + [ + { + "constant": false, + "id": 1035, + "mutability": "mutable", + "name": "adjustedFeeAmount", + "nameLocation": "29350:17:4", + "nodeType": "VariableDeclaration", + "scope": 1107, + "src": "29342:25:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1034, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "29342:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1036, + "nodeType": "VariableDeclarationStatement", + "src": "29342:25:4" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1041, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "id": 1037, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "29381:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1038, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29394:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 1403, + "src": "29381:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 1039, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29402:6:4", + "memberName": "amount", + "nodeType": "MemberAccess", + "referencedDeclaration": 1435, + "src": "29381:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 1040, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "29411:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "29381:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1069, + "nodeType": "IfStatement", + "src": "29377:497:4", + "trueBody": + { + "id": 1068, + "nodeType": "Block", + "src": "29414:460:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 1050, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "id": 1043, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "29549:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1044, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29562:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 1403, + "src": "29549:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 1045, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29570:15:4", + "memberName": "feeTokenAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1433, + "src": "29549:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 1048, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "29597:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1047, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "29589:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 1046, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "29589:7:4", + "typeDescriptions": {} + } + }, + "id": 1049, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "29589:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "29549:50:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a207a65726f2066656520617373657420636f6e74726163742061646472657373", + "id": 1051, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "29617:54:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_f59603fcdda5ee2bb2d0f07d6e9b43b5bb3ed9ab2df0ad87d6ed06efd082db17", + "typeString": "literal_string \"TeleporterMessenger: zero fee asset contract address\"" + }, + "value": "TeleporterMessenger: zero fee asset contract address" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f59603fcdda5ee2bb2d0f07d6e9b43b5bb3ed9ab2df0ad87d6ed06efd082db17", + "typeString": "literal_string \"TeleporterMessenger: zero fee asset contract address\"" + } + ], + "id": 1042, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "29524:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1052, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "29524:161:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1053, + "nodeType": "ExpressionStatement", + "src": "29524:161:4" + }, + { + "expression": + { + "id": 1066, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 1054, + "name": "adjustedFeeAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1035, + "src": "29700:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "arguments": + [ + { + "arguments": + [ + { + "expression": + { + "expression": + { + "id": 1058, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "29783:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1059, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29796:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 1403, + "src": "29783:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 1060, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29804:15:4", + "memberName": "feeTokenAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1433, + "src": "29783:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 1057, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2099, + "src": "29776:6:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_IERC20_$2099_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 1061, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "29776:44:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "expression": + { + "expression": + { + "id": 1062, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "29822:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1063, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29835:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 1403, + "src": "29822:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 1064, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29843:6:4", + "memberName": "amount", + "nodeType": "MemberAccess", + "referencedDeclaration": 1435, + "src": "29822:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": + { + "id": 1055, + "name": "SafeERC20TransferFrom", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "29720:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_SafeERC20TransferFrom_$2021_$", + "typeString": "type(library SafeERC20TransferFrom)" + } + }, + "id": 1056, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "29742:16:4", + "memberName": "safeTransferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 1964, + "src": "29720:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (contract IERC20,uint256) returns (uint256)" + } + }, + "id": 1065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "29720:143:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "29700:163:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1067, + "nodeType": "ExpressionStatement", + "src": "29700:163:4" + } + ] + } + }, + { + "assignments": + [ + 1072 + ], + "declarations": + [ + { + "constant": false, + "id": 1072, + "mutability": "mutable", + "name": "adjustedFeeInfo", + "nameLocation": "30136:15:4", + "nodeType": "VariableDeclaration", + "scope": 1107, + "src": "30111:40:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo" + }, + "typeName": + { + "id": 1071, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1070, + "name": "TeleporterFeeInfo", + "nameLocations": + [ + "30111:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1436, + "src": "30111:17:4" + }, + "referencedDeclaration": 1436, + "src": "30111:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_storage_ptr", + "typeString": "struct TeleporterFeeInfo" + } + }, + "visibility": "internal" + } + ], + "id": 1079, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "expression": + { + "id": 1074, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "30203:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1075, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "30216:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 1403, + "src": "30203:20:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 1076, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "30224:15:4", + "memberName": "feeTokenAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1433, + "src": "30203:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1077, + "name": "adjustedFeeAmount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1035, + "src": "30261:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1073, + "name": "TeleporterFeeInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1436, + "src": "30154:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_TeleporterFeeInfo_$1436_storage_ptr_$", + "typeString": "type(struct TeleporterFeeInfo storage pointer)" + } + }, + "id": 1078, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "nameLocations": + [ + "30186:15:4", + "30253:6:4" + ], + "names": + [ + "feeTokenAddress", + "amount" + ], + "nodeType": "FunctionCall", + "src": "30154:135:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "30111:178:4" + }, + { + "expression": + { + "id": 1089, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "id": 1080, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "30299:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 1082, + "indexExpression": + { + "id": 1081, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 999, + "src": "30315:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "30299:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 1085, + "name": "teleporterMessageBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1028, + "src": "30381:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1084, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "30371:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1086, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "30371:33:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1087, + "name": "adjustedFeeInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1072, + "src": "30427:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + ], + "id": 1083, + "name": "SentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "30328:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_struct$_SentMessageInfo_$42_storage_ptr_$", + "typeString": "type(struct TeleporterMessenger.SentMessageInfo storage pointer)" + } + }, + "id": 1088, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "nameLocations": + [ + "30358:11:4", + "30418:7:4" + ], + "names": + [ + "messageHash", + "feeInfo" + ], + "nodeType": "FunctionCall", + "src": "30328:125:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "src": "30299:154:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "id": 1090, + "nodeType": "ExpressionStatement", + "src": "30299:154:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 1092, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 999, + "src": "30504:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 1093, + "name": "messageInput", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "30515:12:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput memory" + } + }, + "id": 1094, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "30528:23:4", + "memberName": "destinationBlockchainID", + "nodeType": "MemberAccess", + "referencedDeclaration": 1398, + "src": "30515:36:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1095, + "name": "teleporterMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1009, + "src": "30553:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + { + "id": 1096, + "name": "adjustedFeeInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1072, + "src": "30572:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + }, + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + ], + "id": 1091, + "name": "SendCrossChainMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1455, + "src": "30469:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$_t_struct$_TeleporterMessage_$1431_memory_ptr_$_t_struct$_TeleporterFeeInfo_$1436_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,struct TeleporterMessage memory,struct TeleporterFeeInfo memory)" + } + }, + "id": 1097, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "30469:128:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1098, + "nodeType": "EmitStatement", + "src": "30464:133:4" + }, + { + "expression": + { + "arguments": + [ + { + "id": 1102, + "name": "teleporterMessageBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1028, + "src": "30692:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "id": 1099, + "name": "WARP_MESSENGER", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49, + "src": "30661:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IWarpMessenger_$1389", + "typeString": "contract IWarpMessenger" + } + }, + "id": 1101, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "30676:15:4", + "memberName": "sendWarpMessage", + "nodeType": "MemberAccess", + "referencedDeclaration": 1363, + "src": "30661:30:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) external returns (bytes32)" + } + }, + "id": 1103, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "30661:54:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1104, + "nodeType": "ExpressionStatement", + "src": "30661:54:4" + }, + { + "expression": + { + "id": 1105, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 999, + "src": "30733:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 987, + "id": 1106, + "nodeType": "Return", + "src": "30726:16:4" + } + ] + }, + "documentation": + { + "id": 976, + "nodeType": "StructuredDocumentation", + "src": "27391:278:4", + "text": " @dev Helper function for sending a teleporter message cross chain.\n Constructs the Teleporter message and sends it through the Warp Messenger precompile,\n and performs fee transfer if necessary.\n Emits a {SendCrossChainMessage} event." + }, + "id": 1108, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_sendTeleporterMessage", + "nameLocation": "27683:22:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 984, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 979, + "mutability": "mutable", + "name": "messageInput", + "nameLocation": "27745:12:4", + "nodeType": "VariableDeclaration", + "scope": 1108, + "src": "27715:42:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_memory_ptr", + "typeString": "struct TeleporterMessageInput" + }, + "typeName": + { + "id": 978, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 977, + "name": "TeleporterMessageInput", + "nameLocations": + [ + "27715:22:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1411, + "src": "27715:22:4" + }, + "referencedDeclaration": 1411, + "src": "27715:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageInput_$1411_storage_ptr", + "typeString": "struct TeleporterMessageInput" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 983, + "mutability": "mutable", + "name": "receipts", + "nameLocation": "27801:8:4", + "nodeType": "VariableDeclaration", + "scope": 1108, + "src": "27767:42:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_memory_ptr_$dyn_memory_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + }, + "typeName": + { + "baseType": + { + "id": 981, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 980, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "27767:24:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "27767:24:4" + }, + "referencedDeclaration": 1396, + "src": "27767:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "id": 982, + "nodeType": "ArrayTypeName", + "src": "27767:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_struct$_TeleporterMessageReceipt_$1396_storage_$dyn_storage_ptr", + "typeString": "struct TeleporterMessageReceipt[]" + } + }, + "visibility": "internal" + } + ], + "src": "27705:110:4" + }, + "returnParameters": + { + "id": 987, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 986, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1108, + "src": "27833:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 985, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "27833:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "27832:9:4" + }, + "scope": 1334, + "src": "27674:3075:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": + { + "id": 1129, + "nodeType": "Block", + "src": "31108:146:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1119, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 1117, + "name": "messageNonce_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1113, + "src": "31126:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "hexValue": "30", + "id": 1118, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "31143:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "31126:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a207a65726f206d657373616765206e6f6e6365", + "id": 1120, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "31146:41:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_e6477a01e64f775c32f28edb4c0797c9f2aa1e600bbf64b0a067da700392f856", + "typeString": "literal_string \"TeleporterMessenger: zero message nonce\"" + }, + "value": "TeleporterMessenger: zero message nonce" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e6477a01e64f775c32f28edb4c0797c9f2aa1e600bbf64b0a067da700392f856", + "typeString": "literal_string \"TeleporterMessenger: zero message nonce\"" + } + ], + "id": 1116, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "31118:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1121, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "31118:70:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1122, + "nodeType": "ExpressionStatement", + "src": "31118:70:4" + }, + { + "expression": + { + "id": 1127, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "id": 1123, + "name": "_receivedMessageNonces", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 77, + "src": "31198:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_uint256_$", + "typeString": "mapping(bytes32 => uint256)" + } + }, + "id": 1125, + "indexExpression": + { + "id": 1124, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1111, + "src": "31221:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "31198:33:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1126, + "name": "messageNonce_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1113, + "src": "31234:13:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "31198:49:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1128, + "nodeType": "ExpressionStatement", + "src": "31198:49:4" + } + ] + }, + "documentation": + { + "id": 1109, + "nodeType": "StructuredDocumentation", + "src": "30755:268:4", + "text": " @dev Marks a message as being received by storing the message nonce associated with the\n given message ID. The message nonce must not be zero in order to be able to distinguish between\n received and unreceived messages based on their ID." + }, + "id": 1130, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_markMessageReceived", + "nameLocation": "31037:20:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1114, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1111, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "31066:9:4", + "nodeType": "VariableDeclaration", + "scope": 1130, + "src": "31058:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1110, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31058:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1113, + "mutability": "mutable", + "name": "messageNonce_", + "nameLocation": "31085:13:4", + "nodeType": "VariableDeclaration", + "scope": 1130, + "src": "31077:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1112, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "31077:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "31057:42:4" + }, + "returnParameters": + { + "id": 1115, + "nodeType": "ParameterList", + "parameters": [], + "src": "31108:0:4" + }, + "scope": 1334, + "src": "31028:226:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": + { + "id": 1194, + "nodeType": "Block", + "src": "31940:1303:4", + "statements": + [ + { + "assignments": + [ + 1142 + ], + "declarations": + [ + { + "constant": false, + "id": 1142, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "31958:9:4", + "nodeType": "VariableDeclaration", + "scope": 1194, + "src": "31950:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1141, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31950:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1149, + "initialValue": + { + "arguments": + [ + { + "id": 1144, + "name": "sourceBlockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1133, + "src": "32002:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1145, + "name": "destinationBlockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1135, + "src": "32023:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 1146, + "name": "receipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1138, + "src": "32049:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "id": 1147, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "32057:20:4", + "memberName": "receivedMessageNonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 1393, + "src": "32049:28:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1143, + "name": "calculateMessageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 928, + "src": "31970:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32,uint256) view returns (bytes32)" + } + }, + "id": 1148, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "31970:117:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "31950:137:4" + }, + { + "assignments": + [ + 1152 + ], + "declarations": + [ + { + "constant": false, + "id": 1152, + "mutability": "mutable", + "name": "messageInfo", + "nameLocation": "32201:11:4", + "nodeType": "VariableDeclaration", + "scope": 1194, + "src": "32178:34:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo" + }, + "typeName": + { + "id": 1151, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1150, + "name": "SentMessageInfo", + "nameLocations": + [ + "32178:15:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 42, + "src": "32178:15:4" + }, + "referencedDeclaration": 42, + "src": "32178:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo" + } + }, + "visibility": "internal" + } + ], + "id": 1156, + "initialValue": + { + "baseExpression": + { + "id": 1153, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "32215:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 1155, + "indexExpression": + { + "id": 1154, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1142, + "src": "32231:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "32215:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "32178:63:4" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1163, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 1157, + "name": "messageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1152, + "src": "32616:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "id": 1158, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "32628:11:4", + "memberName": "messageHash", + "nodeType": "MemberAccess", + "referencedDeclaration": 38, + "src": "32616:23:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "arguments": + [ + { + "hexValue": "30", + "id": 1161, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "32651:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1160, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "32643:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": + { + "id": 1159, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "32643:7:4", + "typeDescriptions": {} + } + }, + "id": 1162, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "32643:10:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "32616:37:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1166, + "nodeType": "IfStatement", + "src": "32612:74:4", + "trueBody": + { + "id": 1165, + "nodeType": "Block", + "src": "32655:31:4", + "statements": + [ + { + "functionReturnParameters": 1140, + "id": 1164, + "nodeType": "Return", + "src": "32669:7:4" + } + ] + } + }, + { + "expression": + { + "id": 1170, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "delete", + "prefix": true, + "src": "32786:33:4", + "subExpression": + { + "baseExpression": + { + "id": 1167, + "name": "sentMessageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 67, + "src": "32793:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_struct$_SentMessageInfo_$42_storage_$", + "typeString": "mapping(bytes32 => struct TeleporterMessenger.SentMessageInfo storage ref)" + } + }, + "id": 1169, + "indexExpression": + { + "id": 1168, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1142, + "src": "32809:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "32793:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_storage", + "typeString": "struct TeleporterMessenger.SentMessageInfo storage ref" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1171, + "nodeType": "ExpressionStatement", + "src": "32786:33:4" + }, + { + "expression": + { + "id": 1183, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "baseExpression": + { + "id": 1172, + "name": "_relayerRewardAmounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 89, + "src": "32965:21:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 1178, + "indexExpression": + { + "expression": + { + "id": 1173, + "name": "receipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1138, + "src": "32987:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "id": 1174, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "32995:20:4", + "memberName": "relayerRewardAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1395, + "src": "32987:28:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "32965:51:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 1179, + "indexExpression": + { + "expression": + { + "expression": + { + "id": 1175, + "name": "messageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1152, + "src": "33017:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "id": 1176, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "33029:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "33017:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 1177, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "33037:15:4", + "memberName": "feeTokenAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1433, + "src": "33017:35:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "32965:88:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "expression": + { + "expression": + { + "id": 1180, + "name": "messageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1152, + "src": "33069:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "id": 1181, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "33081:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "33069:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + }, + "id": 1182, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "33089:6:4", + "memberName": "amount", + "nodeType": "MemberAccess", + "referencedDeclaration": 1435, + "src": "33069:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "32965:130:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1184, + "nodeType": "ExpressionStatement", + "src": "32965:130:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 1186, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1142, + "src": "33140:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1187, + "name": "destinationBlockchainID_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1135, + "src": "33151:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 1188, + "name": "receipt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1138, + "src": "33177:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt memory" + } + }, + "id": 1189, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "33185:20:4", + "memberName": "relayerRewardAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1395, + "src": "33177:28:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 1190, + "name": "messageInfo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1152, + "src": "33207:11:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_SentMessageInfo_$42_memory_ptr", + "typeString": "struct TeleporterMessenger.SentMessageInfo memory" + } + }, + "id": 1191, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "33219:7:4", + "memberName": "feeInfo", + "nodeType": "MemberAccess", + "referencedDeclaration": 41, + "src": "33207:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_struct$_TeleporterFeeInfo_$1436_memory_ptr", + "typeString": "struct TeleporterFeeInfo memory" + } + ], + "id": 1185, + "name": "ReceiptReceived", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1506, + "src": "33111:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$_t_address_$_t_struct$_TeleporterFeeInfo_$1436_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,address,struct TeleporterFeeInfo memory)" + } + }, + "id": 1192, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "33111:125:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1193, + "nodeType": "EmitStatement", + "src": "33106:130:4" + } + ] + }, + "documentation": + { + "id": 1131, + "nodeType": "StructuredDocumentation", + "src": "31260:511:4", + "text": " @dev Records the receival of a receipt for a message previously sent to the `destinationBlockchainID` with the given `messageID`.\n Returns early if a receipt was already previously received for this message, or if the message never existed. Otherwise, deletes\n the message information from `sentMessageInfo` and increments the reward redeemable by the specified relayer reward address.\n Emits a {ReceiptReceived} event if the receipt was successfully received." + }, + "id": 1195, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_markReceipt", + "nameLocation": "31785:12:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1139, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1133, + "mutability": "mutable", + "name": "sourceBlockchainID_", + "nameLocation": "31815:19:4", + "nodeType": "VariableDeclaration", + "scope": 1195, + "src": "31807:27:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1132, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31807:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1135, + "mutability": "mutable", + "name": "destinationBlockchainID_", + "nameLocation": "31852:24:4", + "nodeType": "VariableDeclaration", + "scope": 1195, + "src": "31844:32:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1134, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "31844:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1138, + "mutability": "mutable", + "name": "receipt", + "nameLocation": "31918:7:4", + "nodeType": "VariableDeclaration", + "scope": 1195, + "src": "31886:39:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_memory_ptr", + "typeString": "struct TeleporterMessageReceipt" + }, + "typeName": + { + "id": 1137, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1136, + "name": "TeleporterMessageReceipt", + "nameLocations": + [ + "31886:24:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1396, + "src": "31886:24:4" + }, + "referencedDeclaration": 1396, + "src": "31886:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessageReceipt_$1396_storage_ptr", + "typeString": "struct TeleporterMessageReceipt" + } + }, + "visibility": "internal" + } + ], + "src": "31797:134:4" + }, + "returnParameters": + { + "id": 1140, + "nodeType": "ParameterList", + "parameters": [], + "src": "31940:0:4" + }, + "scope": 1334, + "src": "31776:1467:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": + { + "id": 1270, + "nodeType": "Block", + "src": "34120:2317:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1211, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 1207, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -7, + "src": "34623:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 1208, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "34623:9:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "expression": + { + "id": 1209, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "34636:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 1210, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "34644:16:4", + "memberName": "requiredGasLimit", + "nodeType": "MemberAccess", + "referencedDeclaration": 1421, + "src": "34636:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "34623:37:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "54656c65706f727465724d657373656e6765723a20696e73756666696369656e7420676173", + "id": 1212, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "34662:39:4", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_85b0dc9e3625a049670fae224d84fd8a1ce0a56432d7462f1047908913a8d05f", + "typeString": "literal_string \"TeleporterMessenger: insufficient gas\"" + }, + "value": "TeleporterMessenger: insufficient gas" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_85b0dc9e3625a049670fae224d84fd8a1ce0a56432d7462f1047908913a8d05f", + "typeString": "literal_string \"TeleporterMessenger: insufficient gas\"" + } + ], + "id": 1206, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "34615:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1213, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "34615:87:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1214, + "nodeType": "ExpressionStatement", + "src": "34615:87:4" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1220, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "expression": + { + "id": 1215, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "35043:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 1216, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "35051:18:4", + "memberName": "destinationAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1419, + "src": "35043:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 1217, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "35070:4:4", + "memberName": "code", + "nodeType": "MemberAccess", + "src": "35043:31:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 1218, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "35075:6:4", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "35043:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 1219, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "35085:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "35043:43:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1229, + "nodeType": "IfStatement", + "src": "35039:162:4", + "trueBody": + { + "id": 1228, + "nodeType": "Block", + "src": "35088:113:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 1222, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1198, + "src": "35131:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1223, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1200, + "src": "35142:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1224, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "35162:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + ], + "id": 1221, + "name": "_storeFailedMessageExecution", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1318, + "src": "35102:28:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_struct$_TeleporterMessage_$1431_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,struct TeleporterMessage memory)" + } + }, + "id": 1225, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "35102:68:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1226, + "nodeType": "ExpressionStatement", + "src": "35102:68:4" + }, + { + "functionReturnParameters": 1205, + "id": 1227, + "nodeType": "Return", + "src": "35184:7:4" + } + ] + } + }, + { + "assignments": + [ + 1231 + ], + "declarations": + [ + { + "constant": false, + "id": 1231, + "mutability": "mutable", + "name": "payload", + "nameLocation": "35379:7:4", + "nodeType": "VariableDeclaration", + "scope": 1270, + "src": "35366:20:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1230, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "35366:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 1243, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 1234, + "name": "ITeleporterReceiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1667, + "src": "35417:19:4", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_contract$_ITeleporterReceiver_$1667_$", + "typeString": "type(contract ITeleporterReceiver)" + } + }, + "id": 1235, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "35437:24:4", + "memberName": "receiveTeleporterMessage", + "nodeType": "MemberAccess", + "referencedDeclaration": 1666, + "src": "35417:44:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_declaration_nonpayable$_t_bytes32_$_t_address_$_t_bytes_calldata_ptr_$returns$__$", + "typeString": "function ITeleporterReceiver.receiveTeleporterMessage(bytes32,address,bytes calldata)" + } + }, + { + "components": + [ + { + "id": 1236, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1200, + "src": "35476:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": + { + "id": 1237, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "35496:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 1238, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "35504:19:4", + "memberName": "originSenderAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1415, + "src": "35496:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 1239, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "35525:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 1240, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "35533:7:4", + "memberName": "message", + "nodeType": "MemberAccess", + "referencedDeclaration": 1430, + "src": "35525:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "id": 1241, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "35475:66:4", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bytes32,address,bytes memory)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_function_declaration_nonpayable$_t_bytes32_$_t_address_$_t_bytes_calldata_ptr_$returns$__$", + "typeString": "function ITeleporterReceiver.receiveTeleporterMessage(bytes32,address,bytes calldata)" + }, + { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bytes32,address,bytes memory)" + } + ], + "expression": + { + "id": 1232, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "35389:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1233, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "35393:10:4", + "memberName": "encodeCall", + "nodeType": "MemberAccess", + "src": "35389:14:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencodecall_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1242, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "35389:162:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35366:185:4" + }, + { + "assignments": + [ + 1245 + ], + "declarations": + [ + { + "constant": false, + "id": 1245, + "mutability": "mutable", + "name": "success", + "nameLocation": "35786:7:4", + "nodeType": "VariableDeclaration", + "scope": 1270, + "src": "35781:12:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 1244, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "35781:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 1253, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 1247, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "35827:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 1248, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "35835:18:4", + "memberName": "destinationAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 1419, + "src": "35827:26:4", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": + { + "id": 1249, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "35855:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + }, + "id": 1250, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "35863:16:4", + "memberName": "requiredGasLimit", + "nodeType": "MemberAccess", + "referencedDeclaration": 1421, + "src": "35855:24:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1251, + "name": "payload", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1231, + "src": "35881:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1246, + "name": "_tryExecuteMessage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1289, + "src": "35808:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bool_$", + "typeString": "function (address,uint256,bytes memory) returns (bool)" + } + }, + "id": 1252, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "35808:81:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35781:108:4" + }, + { + "condition": + { + "id": 1255, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "36246:8:4", + "subExpression": + { + "id": 1254, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1245, + "src": "36247:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1264, + "nodeType": "IfStatement", + "src": "36242:127:4", + "trueBody": + { + "id": 1263, + "nodeType": "Block", + "src": "36256:113:4", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 1257, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1198, + "src": "36299:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1258, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1200, + "src": "36310:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1259, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1203, + "src": "36330:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + ], + "id": 1256, + "name": "_storeFailedMessageExecution", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1318, + "src": "36270:28:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_struct$_TeleporterMessage_$1431_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,struct TeleporterMessage memory)" + } + }, + "id": 1260, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "36270:68:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1261, + "nodeType": "ExpressionStatement", + "src": "36270:68:4" + }, + { + "functionReturnParameters": 1205, + "id": 1262, + "nodeType": "Return", + "src": "36352:7:4" + } + ] + } + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 1266, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1198, + "src": "36400:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1267, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1200, + "src": "36411:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 1265, + "name": "MessageExecuted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1480, + "src": "36384:15:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32)" + } + }, + "id": 1268, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "36384:46:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1269, + "nodeType": "EmitStatement", + "src": "36379:51:4" + } + ] + }, + "documentation": + { + "id": 1196, + "nodeType": "StructuredDocumentation", + "src": "33249:707:4", + "text": " @dev Attempts to execute the newly received message.\n Only revert in the event that the message deliverer (relayer) did not provide enough gas to handle the execution\n (including possibly storing a failed message in state). All execution specific errors (i.e. invalid call data, etc)\n that are not in the relayer's control are caught and handled properly.\n Emits a {MessageExecuted} event if the call on destination address is successful.\n Emits a {MessageExecutionFailed} event if the call on destination address fails with formatted call data.\n Requirements:\n - There is enough gas left to cover `message.requiredGasLimit`." + }, + "id": 1271, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_handleInitialMessageExecution", + "nameLocation": "33970:30:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1204, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1198, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "34018:9:4", + "nodeType": "VariableDeclaration", + "scope": 1271, + "src": "34010:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1197, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "34010:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1200, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "34045:18:4", + "nodeType": "VariableDeclaration", + "scope": 1271, + "src": "34037:26:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1199, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "34037:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1203, + "mutability": "mutable", + "name": "message", + "nameLocation": "34098:7:4", + "nodeType": "VariableDeclaration", + "scope": 1271, + "src": "34073:32:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1202, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1201, + "name": "TeleporterMessage", + "nameLocations": + [ + "34073:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "34073:17:4" + }, + "referencedDeclaration": 1431, + "src": "34073:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "34000:111:4" + }, + "returnParameters": + { + "id": 1205, + "nodeType": "ParameterList", + "parameters": [], + "src": "34120:0:4" + }, + "scope": 1334, + "src": "33961:2476:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": + { + "id": 1288, + "nodeType": "Block", + "src": "36580:1205:4", + "statements": + [ + { + "assignments": + [ + 1283 + ], + "declarations": + [ + { + "constant": false, + "id": 1283, + "mutability": "mutable", + "name": "success", + "nameLocation": "37046:7:4", + "nodeType": "VariableDeclaration", + "scope": 1288, + "src": "37041:12:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 1282, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "37041:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 1284, + "nodeType": "VariableDeclarationStatement", + "src": "37041:12:4" + }, + { + "AST": + { + "nativeSrc": "37128:627:4", + "nodeType": "YulBlock", + "src": "37128:627:4", + "statements": + [ + { + "nativeSrc": "37142:603:4", + "nodeType": "YulAssignment", + "src": "37142:603:4", + "value": + { + "arguments": + [ + { + "name": "gasLimit", + "nativeSrc": "37195:8:4", + "nodeType": "YulIdentifier", + "src": "37195:8:4" + }, + { + "name": "target", + "nativeSrc": "37253:6:4", + "nodeType": "YulIdentifier", + "src": "37253:6:4" + }, + { + "kind": "number", + "nativeSrc": "37296:1:4", + "nodeType": "YulLiteral", + "src": "37296:1:4", + "type": "", + "value": "0" + }, + { + "arguments": + [ + { + "name": "payload", + "nativeSrc": "37337:7:4", + "nodeType": "YulIdentifier", + "src": "37337:7:4" + }, + { + "kind": "number", + "nativeSrc": "37346:4:4", + "nodeType": "YulLiteral", + "src": "37346:4:4", + "type": "", + "value": "0x20" + } + ], + "functionName": + { + "name": "add", + "nativeSrc": "37333:3:4", + "nodeType": "YulIdentifier", + "src": "37333:3:4" + }, + "nativeSrc": "37333:18:4", + "nodeType": "YulFunctionCall", + "src": "37333:18:4" + }, + { + "arguments": + [ + { + "name": "payload", + "nativeSrc": "37519:7:4", + "nodeType": "YulIdentifier", + "src": "37519:7:4" + } + ], + "functionName": + { + "name": "mload", + "nativeSrc": "37513:5:4", + "nodeType": "YulIdentifier", + "src": "37513:5:4" + }, + "nativeSrc": "37513:14:4", + "nodeType": "YulFunctionCall", + "src": "37513:14:4" + }, + { + "kind": "number", + "nativeSrc": "37678:1:4", + "nodeType": "YulLiteral", + "src": "37678:1:4", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nativeSrc": "37711:1:4", + "nodeType": "YulLiteral", + "src": "37711:1:4", + "type": "", + "value": "0" + } + ], + "functionName": + { + "name": "call", + "nativeSrc": "37169:4:4", + "nodeType": "YulIdentifier", + "src": "37169:4:4" + }, + "nativeSrc": "37169:576:4", + "nodeType": "YulFunctionCall", + "src": "37169:576:4" + }, + "variableNames": + [ + { + "name": "success", + "nativeSrc": "37142:7:4", + "nodeType": "YulIdentifier", + "src": "37142:7:4" + } + ] + } + ] + }, + "evmVersion": "shanghai", + "externalReferences": + [ + { + "declaration": 1275, + "isOffset": false, + "isSlot": false, + "src": "37195:8:4", + "valueSize": 1 + }, + { + "declaration": 1277, + "isOffset": false, + "isSlot": false, + "src": "37337:7:4", + "valueSize": 1 + }, + { + "declaration": 1277, + "isOffset": false, + "isSlot": false, + "src": "37519:7:4", + "valueSize": 1 + }, + { + "declaration": 1283, + "isOffset": false, + "isSlot": false, + "src": "37142:7:4", + "valueSize": 1 + }, + { + "declaration": 1273, + "isOffset": false, + "isSlot": false, + "src": "37253:6:4", + "valueSize": 1 + } + ], + "id": 1285, + "nodeType": "InlineAssembly", + "src": "37119:636:4" + }, + { + "expression": + { + "id": 1286, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1283, + "src": "37771:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 1281, + "id": 1287, + "nodeType": "Return", + "src": "37764:14:4" + } + ] + }, + "id": 1289, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_tryExecuteMessage", + "nameLocation": "36452:18:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1278, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1273, + "mutability": "mutable", + "name": "target", + "nameLocation": "36488:6:4", + "nodeType": "VariableDeclaration", + "scope": 1289, + "src": "36480:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1272, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "36480:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1275, + "mutability": "mutable", + "name": "gasLimit", + "nameLocation": "36512:8:4", + "nodeType": "VariableDeclaration", + "scope": 1289, + "src": "36504:16:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1274, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "36504:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1277, + "mutability": "mutable", + "name": "payload", + "nameLocation": "36543:7:4", + "nodeType": "VariableDeclaration", + "scope": 1289, + "src": "36530:20:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 1276, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "36530:5:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "36470:86:4" + }, + "returnParameters": + { + "id": 1281, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1280, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1289, + "src": "36574:4:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 1279, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "36574:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "36573:6:4" + }, + "scope": 1334, + "src": "36443:1342:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": + { + "id": 1317, + "nodeType": "Block", + "src": "38150:261:4", + "statements": + [ + { + "expression": + { + "id": 1309, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "id": 1300, + "name": "receivedFailedMessageHashes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 72, + "src": "38160:27:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_bytes32_$", + "typeString": "mapping(bytes32 => bytes32)" + } + }, + "id": 1302, + "indexExpression": + { + "id": 1301, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1292, + "src": "38188:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "38160:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 1306, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1297, + "src": "38222:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + ], + "expression": + { + "id": 1304, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "38211:3:4", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1305, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "38215:6:4", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "38211:10:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1307, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "38211:19:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1303, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "38201:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1308, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "38201:30:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "38160:71:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1310, + "nodeType": "ExpressionStatement", + "src": "38160:71:4" + }, + { + "eventCall": + { + "arguments": + [ + { + "id": 1312, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1292, + "src": "38365:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1313, + "name": "sourceBlockchainID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1294, + "src": "38376:18:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1314, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1297, + "src": "38396:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage memory" + } + ], + "id": 1311, + "name": "MessageExecutionFailed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1473, + "src": "38342:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_bytes32_$_t_struct$_TeleporterMessage_$1431_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes32,struct TeleporterMessage memory)" + } + }, + "id": 1315, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "38342:62:4", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1316, + "nodeType": "EmitStatement", + "src": "38337:67:4" + } + ] + }, + "documentation": + { + "id": 1290, + "nodeType": "StructuredDocumentation", + "src": "37791:197:4", + "text": " @dev Stores the hash of a message that has been successfully received but fails to execute properly\n such that the message execution can be retried by anyone in the future." + }, + "id": 1318, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_storeFailedMessageExecution", + "nameLocation": "38002:28:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1298, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1292, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "38048:9:4", + "nodeType": "VariableDeclaration", + "scope": 1318, + "src": "38040:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1291, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38040:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1294, + "mutability": "mutable", + "name": "sourceBlockchainID", + "nameLocation": "38075:18:4", + "nodeType": "VariableDeclaration", + "scope": 1318, + "src": "38067:26:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1293, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38067:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1297, + "mutability": "mutable", + "name": "message", + "nameLocation": "38128:7:4", + "nodeType": "VariableDeclaration", + "scope": 1318, + "src": "38103:32:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_memory_ptr", + "typeString": "struct TeleporterMessage" + }, + "typeName": + { + "id": 1296, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1295, + "name": "TeleporterMessage", + "nameLocations": + [ + "38103:17:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1431, + "src": "38103:17:4" + }, + "referencedDeclaration": 1431, + "src": "38103:17:4", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_TeleporterMessage_$1431_storage_ptr", + "typeString": "struct TeleporterMessage" + } + }, + "visibility": "internal" + } + ], + "src": "38030:111:4" + }, + "returnParameters": + { + "id": 1299, + "nodeType": "ParameterList", + "parameters": [], + "src": "38150:0:4" + }, + "scope": 1334, + "src": "37993:418:4", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": + { + "id": 1332, + "nodeType": "Block", + "src": "38662:62:4", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1330, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "baseExpression": + { + "id": 1326, + "name": "_receivedMessageNonces", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 77, + "src": "38679:22:4", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_bytes32_$_t_uint256_$", + "typeString": "mapping(bytes32 => uint256)" + } + }, + "id": 1328, + "indexExpression": + { + "id": 1327, + "name": "messageID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1321, + "src": "38702:9:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "38679:33:4", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "hexValue": "30", + "id": 1329, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "38716:1:4", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "38679:38:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 1325, + "id": 1331, + "nodeType": "Return", + "src": "38672:45:4" + } + ] + }, + "documentation": + { + "id": 1319, + "nodeType": "StructuredDocumentation", + "src": "38417:153:4", + "text": " @dev Checks if a given message has been received.\n @return A boolean representing if the given message has been received or not." + }, + "id": 1333, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_messageReceived", + "nameLocation": "38584:16:4", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1322, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1321, + "mutability": "mutable", + "name": "messageID", + "nameLocation": "38618:9:4", + "nodeType": "VariableDeclaration", + "scope": 1333, + "src": "38610:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 1320, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "38610:7:4", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "38600:33:4" + }, + "returnParameters": + { + "id": 1325, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1324, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1333, + "src": "38656:4:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 1323, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "38656:4:4", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "38655:6:4" + }, + "scope": 1334, + "src": "38575:149:4", + "stateMutability": "view", + "virtual": false, + "visibility": "private" + } + ], + "scope": 1335, + "src": "1323:37403:4", + "usedErrors": + [ + 2116, + 3487, + 3492, + 3495 + ], + "usedEvents": + [ + 1442, + 1455, + 1463, + 1473, + 1480, + 1494, + 1506, + 1515 + ] + } + ], + "src": "145:38582:4" + }, + "id": 4 + }, + "icm-contracts/contracts/utilities/ReentrancyGuards.sol": + { + "AST": + { + "absolutePath": "icm-contracts/contracts/utilities/ReentrancyGuards.sol", + "exportedSymbols": + { + "ReentrancyGuards": + [ + 1934 + ] + }, + "id": 1935, + "license": "LicenseRef-Ecosystem", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1872, + "literals": + [ + "solidity", + "0.8", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "145:23:5" + }, + { + "abstract": true, + "baseContracts": [], + "canonicalName": "ReentrancyGuards", + "contractDependencies": [], + "contractKind": "contract", + "documentation": + { + "id": 1873, + "nodeType": "StructuredDocumentation", + "src": "170:587:5", + "text": " @dev Abstract contract that helps implement reentrancy guards between functions for sending and receiving.\n Consecutive calls for sending functions should work together, same for receive functions, but recursive calls\n should be detected as a reentrancy and revert.\n Calls between send and receive functions should also be allowed, but not in the case it ends up being a recursive\n send or receive call. For example the following should fail: send -> receive -> send.\n @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md" + }, + "fullyImplemented": true, + "id": 1934, + "linearizedBaseContracts": + [ + 1934 + ], + "name": "ReentrancyGuards", + "nameLocation": "776:16:5", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": true, + "id": 1876, + "mutability": "constant", + "name": "_NOT_ENTERED", + "nameLocation": "867:12:5", + "nodeType": "VariableDeclaration", + "scope": 1934, + "src": "841:42:5", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1874, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "841:7:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "hexValue": "31", + "id": 1875, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "882:1:5", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 1879, + "mutability": "constant", + "name": "_ENTERED", + "nameLocation": "915:8:5", + "nodeType": "VariableDeclaration", + "scope": 1934, + "src": "889:38:5", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1877, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "889:7:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "hexValue": "32", + "id": 1878, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "926:1:5", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1881, + "mutability": "mutable", + "name": "_sendEntered", + "nameLocation": "949:12:5", + "nodeType": "VariableDeclaration", + "scope": 1934, + "src": "933:28:5", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1880, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "933:7:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "private" + }, + { + "constant": false, + "id": 1883, + "mutability": "mutable", + "name": "_receiveEntered", + "nameLocation": "983:15:5", + "nodeType": "VariableDeclaration", + "scope": 1934, + "src": "967:31:5", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1882, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "967:7:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "private" + }, + { + "body": + { + "id": 1901, + "nodeType": "Block", + "src": "1291:174:5", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1888, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 1886, + "name": "_sendEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1881, + "src": "1309:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "id": 1887, + "name": "_NOT_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1876, + "src": "1325:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1309:28:5", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5265656e7472616e63794775617264733a2073656e646572207265656e7472616e6379", + "id": 1889, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1339:37:5", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_5667a945c0587978f731649c9cef28edf568a3079ab16569a0e6ed563fac2146", + "typeString": "literal_string \"ReentrancyGuards: sender reentrancy\"" + }, + "value": "ReentrancyGuards: sender reentrancy" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5667a945c0587978f731649c9cef28edf568a3079ab16569a0e6ed563fac2146", + "typeString": "literal_string \"ReentrancyGuards: sender reentrancy\"" + } + ], + "id": 1885, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "1301:7:5", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1301:76:5", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1891, + "nodeType": "ExpressionStatement", + "src": "1301:76:5" + }, + { + "expression": + { + "id": 1894, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 1892, + "name": "_sendEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1881, + "src": "1387:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1893, + "name": "_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1879, + "src": "1402:8:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1387:23:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1895, + "nodeType": "ExpressionStatement", + "src": "1387:23:5" + }, + { + "id": 1896, + "nodeType": "PlaceholderStatement", + "src": "1420:1:5" + }, + { + "expression": + { + "id": 1899, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 1897, + "name": "_sendEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1881, + "src": "1431:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1898, + "name": "_NOT_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1876, + "src": "1446:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1431:27:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1900, + "nodeType": "ExpressionStatement", + "src": "1431:27:5" + } + ] + }, + "id": 1902, + "name": "senderNonReentrant", + "nameLocation": "1270:18:5", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 1884, + "nodeType": "ParameterList", + "parameters": [], + "src": "1288:2:5" + }, + "src": "1261:204:5", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 1920, + "nodeType": "Block", + "src": "1767:185:5", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1907, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 1905, + "name": "_receiveEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1883, + "src": "1785:15:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "id": 1906, + "name": "_NOT_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1876, + "src": "1804:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1785:31:5", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5265656e7472616e63794775617264733a207265636569766572207265656e7472616e6379", + "id": 1908, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1818:39:5", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_c2c66bfd13b536a900a41cb3878b25a2c6e77d745398e61cc323a19049fb356c", + "typeString": "literal_string \"ReentrancyGuards: receiver reentrancy\"" + }, + "value": "ReentrancyGuards: receiver reentrancy" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2c66bfd13b536a900a41cb3878b25a2c6e77d745398e61cc323a19049fb356c", + "typeString": "literal_string \"ReentrancyGuards: receiver reentrancy\"" + } + ], + "id": 1904, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "1777:7:5", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 1909, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1777:81:5", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1910, + "nodeType": "ExpressionStatement", + "src": "1777:81:5" + }, + { + "expression": + { + "id": 1913, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 1911, + "name": "_receiveEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1883, + "src": "1868:15:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1912, + "name": "_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1879, + "src": "1886:8:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1868:26:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1914, + "nodeType": "ExpressionStatement", + "src": "1868:26:5" + }, + { + "id": 1915, + "nodeType": "PlaceholderStatement", + "src": "1904:1:5" + }, + { + "expression": + { + "id": 1918, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 1916, + "name": "_receiveEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1883, + "src": "1915:15:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1917, + "name": "_NOT_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1876, + "src": "1933:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1915:30:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1919, + "nodeType": "ExpressionStatement", + "src": "1915:30:5" + } + ] + }, + "id": 1921, + "name": "receiverNonReentrant", + "nameLocation": "1744:20:5", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 1903, + "nodeType": "ParameterList", + "parameters": [], + "src": "1764:2:5" + }, + "src": "1735:217:5", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 1932, + "nodeType": "Block", + "src": "1972:84:5", + "statements": + [ + { + "expression": + { + "id": 1926, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 1924, + "name": "_sendEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1881, + "src": "1982:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1925, + "name": "_NOT_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1876, + "src": "1997:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1982:27:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1927, + "nodeType": "ExpressionStatement", + "src": "1982:27:5" + }, + { + "expression": + { + "id": 1930, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 1928, + "name": "_receiveEntered", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1883, + "src": "2019:15:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 1929, + "name": "_NOT_ENTERED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1876, + "src": "2037:12:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2019:30:5", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1931, + "nodeType": "ExpressionStatement", + "src": "2019:30:5" + } + ] + }, + "id": 1933, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1922, + "nodeType": "ParameterList", + "parameters": [], + "src": "1969:2:5" + }, + "returnParameters": + { + "id": 1923, + "nodeType": "ParameterList", + "parameters": [], + "src": "1972:0:5" + }, + "scope": 1934, + "src": "1958:98:5", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 1935, + "src": "758:1300:5", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "145:1914:5" + }, + "id": 5 + }, + "icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol": + { + "AST": + { + "absolutePath": "icm-contracts/contracts/utilities/SafeERC20TransferFrom.sol", + "exportedSymbols": + { + "IERC20": + [ + 2099 + ], + "SafeERC20": + [ + 2389 + ], + "SafeERC20TransferFrom": + [ + 2021 + ] + }, + "id": 2022, + "license": "LicenseRef-Ecosystem", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1936, + "literals": + [ + "solidity", + "0.8", + ".25" + ], + "nodeType": "PragmaDirective", + "src": "145:23:6" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol", + "file": "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol", + "id": 1938, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2022, + "sourceUnit": 2100, + "src": "170:76:6", + "symbolAliases": + [ + { + "foreign": + { + "id": 1937, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2099, + "src": "178:6:6", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol", + "file": "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol", + "id": 1940, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2022, + "sourceUnit": 2390, + "src": "247:88:6", + "symbolAliases": + [ + { + "foreign": + { + "id": 1939, + "name": "SafeERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2389, + "src": "255:9:6", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "SafeERC20TransferFrom", + "contractDependencies": [], + "contractKind": "library", + "documentation": + { + "id": 1941, + "nodeType": "StructuredDocumentation", + "src": "337:626:6", + "text": " @dev Provides a wrapper used for calling an ERC20 transferFrom method\n to receive tokens to a contract from msg.sender.\n Checks the balance of the contract using the library before and after the call to safeTransferFrom, and\n returns balance increase. Designed for safely handling ERC20 \"fee on transfer\" and \"burn on transfer\" implementations.\n Note: A reentrancy guard must always be used when calling token.safeTransferFrom in order to\n prevent against possible \"before-after\" pattern vulnerabilities.\n @custom:security-contact https://github.com/ava-labs/icm-contracts/blob/main/SECURITY.md" + }, + "fullyImplemented": true, + "id": 2021, + "linearizedBaseContracts": + [ + 2021 + ], + "name": "SafeERC20TransferFrom", + "nameLocation": "972:21:6", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "global": false, + "id": 1945, + "libraryName": + { + "id": 1942, + "name": "SafeERC20", + "nameLocations": + [ + "1006:9:6" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2389, + "src": "1006:9:6" + }, + "nodeType": "UsingForDirective", + "src": "1000:27:6", + "typeName": + { + "id": 1944, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1943, + "name": "IERC20", + "nameLocations": + [ + "1020:6:6" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "1020:6:6" + }, + "referencedDeclaration": 2099, + "src": "1020:6:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + } + }, + { + "body": + { + "id": 1963, + "nodeType": "Block", + "src": "1415:67:6", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 1957, + "name": "erc20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1949, + "src": "1449:5:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "expression": + { + "id": 1958, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "1456:3:6", + "typeDescriptions": + { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 1959, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1460:6:6", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "1456:10:6", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1960, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1951, + "src": "1468:6:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1956, + "name": "safeTransferFrom", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 1964, + 2020 + ], + "referencedDeclaration": 2020, + "src": "1432:16:6", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_address_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (contract IERC20,address,uint256) returns (uint256)" + } + }, + "id": 1961, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1432:43:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 1955, + "id": 1962, + "nodeType": "Return", + "src": "1425:50:6" + } + ] + }, + "documentation": + { + "id": 1946, + "nodeType": "StructuredDocumentation", + "src": "1033:239:6", + "text": " @dev Checks the balance of the contract before and after the call to safeTransferFrom, and returns the balance\n increase. Designed for safely handling ERC20 \"fee on transfer\" and \"burn on transfer\" implementations." + }, + "id": 1964, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "safeTransferFrom", + "nameLocation": "1341:16:6", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1952, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1949, + "mutability": "mutable", + "name": "erc20", + "nameLocation": "1365:5:6", + "nodeType": "VariableDeclaration", + "scope": 1964, + "src": "1358:12:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 1948, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1947, + "name": "IERC20", + "nameLocations": + [ + "1358:6:6" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "1358:6:6" + }, + "referencedDeclaration": 2099, + "src": "1358:6:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1951, + "mutability": "mutable", + "name": "amount", + "nameLocation": "1380:6:6", + "nodeType": "VariableDeclaration", + "scope": 1964, + "src": "1372:14:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1950, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1372:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1357:30:6" + }, + "returnParameters": + { + "id": 1955, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1954, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1964, + "src": "1406:7:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1953, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1406:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1405:9:6" + }, + "scope": 2021, + "src": "1332:150:6", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2019, + "nodeType": "Block", + "src": "2381:337:6", + "statements": + [ + { + "assignments": + [ + 1978 + ], + "declarations": + [ + { + "constant": false, + "id": 1978, + "mutability": "mutable", + "name": "balanceBefore", + "nameLocation": "2399:13:6", + "nodeType": "VariableDeclaration", + "scope": 2019, + "src": "2391:21:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1977, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2391:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1986, + "initialValue": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 1983, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "2439:4:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_SafeERC20TransferFrom_$2021", + "typeString": "library SafeERC20TransferFrom" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_SafeERC20TransferFrom_$2021", + "typeString": "library SafeERC20TransferFrom" + } + ], + "id": 1982, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2431:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 1981, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2431:7:6", + "typeDescriptions": {} + } + }, + "id": 1984, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2431:13:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": + { + "id": 1979, + "name": "erc20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1968, + "src": "2415:5:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 1980, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2421:9:6", + "memberName": "balanceOf", + "nodeType": "MemberAccess", + "referencedDeclaration": 2056, + "src": "2415:15:6", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view external returns (uint256)" + } + }, + "id": 1985, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2415:30:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2391:54:6" + }, + { + "expression": + { + "arguments": + [ + { + "id": 1990, + "name": "from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1970, + "src": "2478:4:6", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": + [ + { + "id": 1993, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "2492:4:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_SafeERC20TransferFrom_$2021", + "typeString": "library SafeERC20TransferFrom" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_SafeERC20TransferFrom_$2021", + "typeString": "library SafeERC20TransferFrom" + } + ], + "id": 1992, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2484:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 1991, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2484:7:6", + "typeDescriptions": {} + } + }, + "id": 1994, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2484:13:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1995, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1972, + "src": "2499:6:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": + { + "id": 1987, + "name": "erc20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1968, + "src": "2455:5:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 1989, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2461:16:6", + "memberName": "safeTransferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 2176, + "src": "2455:22:6", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_address_$_t_address_$_t_uint256_$returns$__$attached_to$_t_contract$_IERC20_$2099_$", + "typeString": "function (contract IERC20,address,address,uint256)" + } + }, + "id": 1996, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2455:51:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1997, + "nodeType": "ExpressionStatement", + "src": "2455:51:6" + }, + { + "assignments": + [ + 1999 + ], + "declarations": + [ + { + "constant": false, + "id": 1999, + "mutability": "mutable", + "name": "balanceAfter", + "nameLocation": "2524:12:6", + "nodeType": "VariableDeclaration", + "scope": 2019, + "src": "2516:20:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1998, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2516:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2007, + "initialValue": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 2004, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "2563:4:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_SafeERC20TransferFrom_$2021", + "typeString": "library SafeERC20TransferFrom" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_SafeERC20TransferFrom_$2021", + "typeString": "library SafeERC20TransferFrom" + } + ], + "id": 2003, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2555:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 2002, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2555:7:6", + "typeDescriptions": {} + } + }, + "id": 2005, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2555:13:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": + { + "id": 2000, + "name": "erc20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1968, + "src": "2539:5:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 2001, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2545:9:6", + "memberName": "balanceOf", + "nodeType": "MemberAccess", + "referencedDeclaration": 2056, + "src": "2539:15:6", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view external returns (uint256)" + } + }, + "id": 2006, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2539:30:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2516:53:6" + }, + { + "expression": + { + "arguments": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2011, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2009, + "name": "balanceAfter", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1999, + "src": "2588:12:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "id": 2010, + "name": "balanceBefore", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1978, + "src": "2603:13:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2588:28:6", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e6f7420696e63726561736564", + "id": 2012, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2618:46:6", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_ab9bf3b5edc3511529ccea14f6e7000c09cbc52ef08e444a542b062f1e5b01dc", + "typeString": "literal_string \"SafeERC20TransferFrom: balance not increased\"" + }, + "value": "SafeERC20TransferFrom: balance not increased" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_ab9bf3b5edc3511529ccea14f6e7000c09cbc52ef08e444a542b062f1e5b01dc", + "typeString": "literal_string \"SafeERC20TransferFrom: balance not increased\"" + } + ], + "id": 2008, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "2580:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 2013, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2580:85:6", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2014, + "nodeType": "ExpressionStatement", + "src": "2580:85:6" + }, + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2017, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2015, + "name": "balanceAfter", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1999, + "src": "2683:12:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "id": 2016, + "name": "balanceBefore", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1978, + "src": "2698:13:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2683:28:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 1976, + "id": 2018, + "nodeType": "Return", + "src": "2676:35:6" + } + ] + }, + "documentation": + { + "id": 1965, + "nodeType": "StructuredDocumentation", + "src": "1542:652:6", + "text": " @dev Checks the balance of the contract before and after the call to safeTransferFrom, and returns the balance\n increase. Designed for safely handling ERC20 \"fee on transfer\" and \"burn on transfer\" implementations.\n Supports passing arbitrary sender address values, allowing its use in ERC-2771 compliant meta-transactions.\n Note: Contracts that use this function must ensure that users cannot pass arbitrary addresses as\n the {from} address for the {transferFrom} call. Proper authorization (such as msg.sender) must\n be required to ensure no one can improperly transfer tokens from any address." + }, + "id": 2020, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "safeTransferFrom", + "nameLocation": "2263:16:6", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1973, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1968, + "mutability": "mutable", + "name": "erc20", + "nameLocation": "2296:5:6", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "2289:12:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 1967, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 1966, + "name": "IERC20", + "nameLocations": + [ + "2289:6:6" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "2289:6:6" + }, + "referencedDeclaration": 2099, + "src": "2289:6:6", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1970, + "mutability": "mutable", + "name": "from", + "nameLocation": "2319:4:6", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "2311:12:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 1969, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2311:7:6", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1972, + "mutability": "mutable", + "name": "amount", + "nameLocation": "2341:6:6", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "2333:14:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1971, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2333:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2279:74:6" + }, + "returnParameters": + { + "id": 1976, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 1975, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "2372:7:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1974, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2372:7:6", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2371:9:6" + }, + "scope": 2021, + "src": "2254:464:6", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2022, + "src": "964:1810:6", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "145:2630:6" + }, + "id": 6 + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": + { + "AST": + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol", + "exportedSymbols": + { + "IERC20": + [ + 2099 + ] + }, + "id": 2100, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 2023, + "literals": + [ + "solidity", + "^", + "0.8", + ".20" + ], + "nodeType": "PragmaDirective", + "src": "106:24:7" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "IERC20", + "contractDependencies": [], + "contractKind": "interface", + "documentation": + { + "id": 2024, + "nodeType": "StructuredDocumentation", + "src": "132:70:7", + "text": " @dev Interface of the ERC20 standard as defined in the EIP." + }, + "fullyImplemented": false, + "id": 2099, + "linearizedBaseContracts": + [ + 2099 + ], + "name": "IERC20", + "nameLocation": "213:6:7", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "anonymous": false, + "documentation": + { + "id": 2025, + "nodeType": "StructuredDocumentation", + "src": "226:158:7", + "text": " @dev Emitted when `value` tokens are moved from one account (`from`) to\n another (`to`).\n Note that `value` may be zero." + }, + "eventSelector": "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "id": 2033, + "name": "Transfer", + "nameLocation": "395:8:7", + "nodeType": "EventDefinition", + "parameters": + { + "id": 2032, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2027, + "indexed": true, + "mutability": "mutable", + "name": "from", + "nameLocation": "420:4:7", + "nodeType": "VariableDeclaration", + "scope": 2033, + "src": "404:20:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2026, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "404:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2029, + "indexed": true, + "mutability": "mutable", + "name": "to", + "nameLocation": "442:2:7", + "nodeType": "VariableDeclaration", + "scope": 2033, + "src": "426:18:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2028, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "426:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2031, + "indexed": false, + "mutability": "mutable", + "name": "value", + "nameLocation": "454:5:7", + "nodeType": "VariableDeclaration", + "scope": 2033, + "src": "446:13:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2030, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "446:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "403:57:7" + }, + "src": "389:72:7" + }, + { + "anonymous": false, + "documentation": + { + "id": 2034, + "nodeType": "StructuredDocumentation", + "src": "467:148:7", + "text": " @dev Emitted when the allowance of a `spender` for an `owner` is set by\n a call to {approve}. `value` is the new allowance." + }, + "eventSelector": "8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "id": 2042, + "name": "Approval", + "nameLocation": "626:8:7", + "nodeType": "EventDefinition", + "parameters": + { + "id": 2041, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2036, + "indexed": true, + "mutability": "mutable", + "name": "owner", + "nameLocation": "651:5:7", + "nodeType": "VariableDeclaration", + "scope": 2042, + "src": "635:21:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2035, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "635:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2038, + "indexed": true, + "mutability": "mutable", + "name": "spender", + "nameLocation": "674:7:7", + "nodeType": "VariableDeclaration", + "scope": 2042, + "src": "658:23:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2037, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "658:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2040, + "indexed": false, + "mutability": "mutable", + "name": "value", + "nameLocation": "691:5:7", + "nodeType": "VariableDeclaration", + "scope": 2042, + "src": "683:13:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2039, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "683:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "634:63:7" + }, + "src": "620:78:7" + }, + { + "documentation": + { + "id": 2043, + "nodeType": "StructuredDocumentation", + "src": "704:65:7", + "text": " @dev Returns the value of tokens in existence." + }, + "functionSelector": "18160ddd", + "id": 2048, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "totalSupply", + "nameLocation": "783:11:7", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2044, + "nodeType": "ParameterList", + "parameters": [], + "src": "794:2:7" + }, + "returnParameters": + { + "id": 2047, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2046, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2048, + "src": "820:7:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2045, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "820:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "819:9:7" + }, + "scope": 2099, + "src": "774:55:7", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 2049, + "nodeType": "StructuredDocumentation", + "src": "835:71:7", + "text": " @dev Returns the value of tokens owned by `account`." + }, + "functionSelector": "70a08231", + "id": 2056, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "balanceOf", + "nameLocation": "920:9:7", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2052, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2051, + "mutability": "mutable", + "name": "account", + "nameLocation": "938:7:7", + "nodeType": "VariableDeclaration", + "scope": 2056, + "src": "930:15:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2050, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "930:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "929:17:7" + }, + "returnParameters": + { + "id": 2055, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2054, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2056, + "src": "970:7:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2053, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "970:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "969:9:7" + }, + "scope": 2099, + "src": "911:68:7", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 2057, + "nodeType": "StructuredDocumentation", + "src": "985:213:7", + "text": " @dev Moves a `value` amount of tokens from the caller's account to `to`.\n Returns a boolean value indicating whether the operation succeeded.\n Emits a {Transfer} event." + }, + "functionSelector": "a9059cbb", + "id": 2066, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "transfer", + "nameLocation": "1212:8:7", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2062, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2059, + "mutability": "mutable", + "name": "to", + "nameLocation": "1229:2:7", + "nodeType": "VariableDeclaration", + "scope": 2066, + "src": "1221:10:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2058, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1221:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2061, + "mutability": "mutable", + "name": "value", + "nameLocation": "1241:5:7", + "nodeType": "VariableDeclaration", + "scope": 2066, + "src": "1233:13:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2060, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1233:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1220:27:7" + }, + "returnParameters": + { + "id": 2065, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2064, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2066, + "src": "1266:4:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2063, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1266:4:7", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "1265:6:7" + }, + "scope": 2099, + "src": "1203:69:7", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 2067, + "nodeType": "StructuredDocumentation", + "src": "1278:264:7", + "text": " @dev Returns the remaining number of tokens that `spender` will be\n allowed to spend on behalf of `owner` through {transferFrom}. This is\n zero by default.\n This value changes when {approve} or {transferFrom} are called." + }, + "functionSelector": "dd62ed3e", + "id": 2076, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "allowance", + "nameLocation": "1556:9:7", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2072, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2069, + "mutability": "mutable", + "name": "owner", + "nameLocation": "1574:5:7", + "nodeType": "VariableDeclaration", + "scope": 2076, + "src": "1566:13:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2068, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1566:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2071, + "mutability": "mutable", + "name": "spender", + "nameLocation": "1589:7:7", + "nodeType": "VariableDeclaration", + "scope": 2076, + "src": "1581:15:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2070, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1581:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "1565:32:7" + }, + "returnParameters": + { + "id": 2075, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2074, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2076, + "src": "1621:7:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2073, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1621:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1620:9:7" + }, + "scope": 2099, + "src": "1547:83:7", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 2077, + "nodeType": "StructuredDocumentation", + "src": "1636:667:7", + "text": " @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n caller's tokens.\n Returns a boolean value indicating whether the operation succeeded.\n IMPORTANT: Beware that changing an allowance with this method brings the risk\n that someone may use both the old and the new allowance by unfortunate\n transaction ordering. One possible solution to mitigate this race\n condition is to first reduce the spender's allowance to 0 and set the\n desired value afterwards:\n https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n Emits an {Approval} event." + }, + "functionSelector": "095ea7b3", + "id": 2086, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "approve", + "nameLocation": "2317:7:7", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2082, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2079, + "mutability": "mutable", + "name": "spender", + "nameLocation": "2333:7:7", + "nodeType": "VariableDeclaration", + "scope": 2086, + "src": "2325:15:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2078, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2325:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2081, + "mutability": "mutable", + "name": "value", + "nameLocation": "2350:5:7", + "nodeType": "VariableDeclaration", + "scope": 2086, + "src": "2342:13:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2080, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2342:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2324:32:7" + }, + "returnParameters": + { + "id": 2085, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2084, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2086, + "src": "2375:4:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2083, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2375:4:7", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "2374:6:7" + }, + "scope": 2099, + "src": "2308:73:7", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 2087, + "nodeType": "StructuredDocumentation", + "src": "2387:297:7", + "text": " @dev Moves a `value` amount of tokens from `from` to `to` using the\n allowance mechanism. `value` is then deducted from the caller's\n allowance.\n Returns a boolean value indicating whether the operation succeeded.\n Emits a {Transfer} event." + }, + "functionSelector": "23b872dd", + "id": 2098, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "transferFrom", + "nameLocation": "2698:12:7", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2094, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2089, + "mutability": "mutable", + "name": "from", + "nameLocation": "2719:4:7", + "nodeType": "VariableDeclaration", + "scope": 2098, + "src": "2711:12:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2088, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2711:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2091, + "mutability": "mutable", + "name": "to", + "nameLocation": "2733:2:7", + "nodeType": "VariableDeclaration", + "scope": 2098, + "src": "2725:10:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2090, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2725:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2093, + "mutability": "mutable", + "name": "value", + "nameLocation": "2745:5:7", + "nodeType": "VariableDeclaration", + "scope": 2098, + "src": "2737:13:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2092, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2737:7:7", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2710:41:7" + }, + "returnParameters": + { + "id": 2097, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2096, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2098, + "src": "2770:4:7", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2095, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2770:4:7", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "2769:6:7" + }, + "scope": 2099, + "src": "2689:87:7", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 2100, + "src": "203:2575:7", + "usedErrors": [], + "usedEvents": + [ + 2033, + 2042 + ] + } + ], + "src": "106:2673:7" + }, + "id": 7 + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol": + { + "AST": + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol", + "exportedSymbols": + { + "IERC20Permit": + [ + 3479 + ] + }, + "id": 3480, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 3445, + "literals": + [ + "solidity", + "^", + "0.8", + ".20" + ], + "nodeType": "PragmaDirective", + "src": "123:24:8" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "IERC20Permit", + "contractDependencies": [], + "contractKind": "interface", + "documentation": + { + "id": 3446, + "nodeType": "StructuredDocumentation", + "src": "149:1963:8", + "text": " @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n need to send a transaction, and thus is not required to hold Ether at all.\n ==== Security Considerations\n There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n considered as an intention to spend the allowance in any specific way. The second is that because permits have\n built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n generally recommended is:\n ```solidity\n function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n doThing(..., value);\n }\n function doThing(..., uint256 value) public {\n token.safeTransferFrom(msg.sender, address(this), value);\n ...\n }\n ```\n Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n {SafeERC20-safeTransferFrom}).\n Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n contracts should have entry points that don't rely on permit." + }, + "fullyImplemented": false, + "id": 3479, + "linearizedBaseContracts": + [ + 3479 + ], + "name": "IERC20Permit", + "nameLocation": "2123:12:8", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "documentation": + { + "id": 3447, + "nodeType": "StructuredDocumentation", + "src": "2142:850:8", + "text": " @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n given ``owner``'s signed approval.\n IMPORTANT: The same issues {IERC20-approve} has related to transaction\n ordering also apply here.\n Emits an {Approval} event.\n Requirements:\n - `spender` cannot be the zero address.\n - `deadline` must be a timestamp in the future.\n - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n over the EIP712-formatted function arguments.\n - the signature must use ``owner``'s current nonce (see {nonces}).\n For more information on the signature format, see the\n https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n section].\n CAUTION: See Security Considerations above." + }, + "functionSelector": "d505accf", + "id": 3464, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "permit", + "nameLocation": "3006:6:8", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3462, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3449, + "mutability": "mutable", + "name": "owner", + "nameLocation": "3030:5:8", + "nodeType": "VariableDeclaration", + "scope": 3464, + "src": "3022:13:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3448, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3022:7:8", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3451, + "mutability": "mutable", + "name": "spender", + "nameLocation": "3053:7:8", + "nodeType": "VariableDeclaration", + "scope": 3464, + "src": "3045:15:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3450, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3045:7:8", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3453, + "mutability": "mutable", + "name": "value", + "nameLocation": "3078:5:8", + "nodeType": "VariableDeclaration", + "scope": 3464, + "src": "3070:13:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3452, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3070:7:8", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3455, + "mutability": "mutable", + "name": "deadline", + "nameLocation": "3101:8:8", + "nodeType": "VariableDeclaration", + "scope": 3464, + "src": "3093:16:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3454, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3093:7:8", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3457, + "mutability": "mutable", + "name": "v", + "nameLocation": "3125:1:8", + "nodeType": "VariableDeclaration", + "scope": 3464, + "src": "3119:7:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": + { + "id": 3456, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "3119:5:8", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3459, + "mutability": "mutable", + "name": "r", + "nameLocation": "3144:1:8", + "nodeType": "VariableDeclaration", + "scope": 3464, + "src": "3136:9:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 3458, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3136:7:8", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3461, + "mutability": "mutable", + "name": "s", + "nameLocation": "3163:1:8", + "nodeType": "VariableDeclaration", + "scope": 3464, + "src": "3155:9:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 3460, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3155:7:8", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "3012:158:8" + }, + "returnParameters": + { + "id": 3463, + "nodeType": "ParameterList", + "parameters": [], + "src": "3179:0:8" + }, + "scope": 3479, + "src": "2997:183:8", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 3465, + "nodeType": "StructuredDocumentation", + "src": "3186:294:8", + "text": " @dev Returns the current nonce for `owner`. This value must be\n included whenever a signature is generated for {permit}.\n Every successful call to {permit} increases ``owner``'s nonce by one. This\n prevents a signature from being used multiple times." + }, + "functionSelector": "7ecebe00", + "id": 3472, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "nonces", + "nameLocation": "3494:6:8", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3468, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3467, + "mutability": "mutable", + "name": "owner", + "nameLocation": "3509:5:8", + "nodeType": "VariableDeclaration", + "scope": 3472, + "src": "3501:13:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3466, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3501:7:8", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "3500:15:8" + }, + "returnParameters": + { + "id": 3471, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3470, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3472, + "src": "3539:7:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3469, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3539:7:8", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3538:9:8" + }, + "scope": 3479, + "src": "3485:63:8", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": + { + "id": 3473, + "nodeType": "StructuredDocumentation", + "src": "3554:128:8", + "text": " @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}." + }, + "functionSelector": "3644e515", + "id": 3478, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "DOMAIN_SEPARATOR", + "nameLocation": "3749:16:8", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3474, + "nodeType": "ParameterList", + "parameters": [], + "src": "3765:2:8" + }, + "returnParameters": + { + "id": 3477, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3476, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3478, + "src": "3791:7:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": + { + "id": 3475, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3791:7:8", + "typeDescriptions": + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "3790:9:8" + }, + "scope": 3479, + "src": "3740:60:8", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + } + ], + "scope": 3480, + "src": "2113:1689:8", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "123:3680:8" + }, + "id": 8 + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol": + { + "AST": + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol", + "exportedSymbols": + { + "Address": + [ + 3732 + ], + "IERC20": + [ + 2099 + ], + "IERC20Permit": + [ + 3479 + ], + "SafeERC20": + [ + 2389 + ] + }, + "id": 2390, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 2101, + "literals": + [ + "solidity", + "^", + "0.8", + ".20" + ], + "nodeType": "PragmaDirective", + "src": "115:24:9" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol", + "file": "../IERC20.sol", + "id": 2103, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2390, + "sourceUnit": 2100, + "src": "141:37:9", + "symbolAliases": + [ + { + "foreign": + { + "id": 2102, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2099, + "src": "149:6:9", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol", + "file": "../extensions/IERC20Permit.sol", + "id": 2105, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2390, + "sourceUnit": 3480, + "src": "179:60:9", + "symbolAliases": + [ + { + "foreign": + { + "id": 2104, + "name": "IERC20Permit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3479, + "src": "187:12:9", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol", + "file": "../../../utils/Address.sol", + "id": 2107, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2390, + "sourceUnit": 3733, + "src": "240:51:9", + "symbolAliases": + [ + { + "foreign": + { + "id": 2106, + "name": "Address", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3732, + "src": "248:7:9", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "SafeERC20", + "contractDependencies": [], + "contractKind": "library", + "documentation": + { + "id": 2108, + "nodeType": "StructuredDocumentation", + "src": "293:457:9", + "text": " @title SafeERC20\n @dev Wrappers around ERC20 operations that throw on failure (when the token\n contract returns false). Tokens that return no value (and instead revert or\n throw on failure) are also supported, non-reverting calls are assumed to be\n successful.\n To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n which allows you to call the safe operations as `token.safeTransfer(...)`, etc." + }, + "fullyImplemented": true, + "id": 2389, + "linearizedBaseContracts": + [ + 2389 + ], + "name": "SafeERC20", + "nameLocation": "759:9:9", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "global": false, + "id": 2111, + "libraryName": + { + "id": 2109, + "name": "Address", + "nameLocations": + [ + "781:7:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 3732, + "src": "781:7:9" + }, + "nodeType": "UsingForDirective", + "src": "775:26:9", + "typeName": + { + "id": 2110, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "793:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + }, + { + "documentation": + { + "id": 2112, + "nodeType": "StructuredDocumentation", + "src": "807:64:9", + "text": " @dev An operation with an ERC20 token failed." + }, + "errorSelector": "5274afe7", + "id": 2116, + "name": "SafeERC20FailedOperation", + "nameLocation": "882:24:9", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 2115, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2114, + "mutability": "mutable", + "name": "token", + "nameLocation": "915:5:9", + "nodeType": "VariableDeclaration", + "scope": 2116, + "src": "907:13:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2113, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "907:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "906:15:9" + }, + "src": "876:46:9" + }, + { + "documentation": + { + "id": 2117, + "nodeType": "StructuredDocumentation", + "src": "928:71:9", + "text": " @dev Indicates a failed `decreaseAllowance` request." + }, + "errorSelector": "e570110f", + "id": 2125, + "name": "SafeERC20FailedDecreaseAllowance", + "nameLocation": "1010:32:9", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 2124, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2119, + "mutability": "mutable", + "name": "spender", + "nameLocation": "1051:7:9", + "nodeType": "VariableDeclaration", + "scope": 2125, + "src": "1043:15:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2118, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1043:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2121, + "mutability": "mutable", + "name": "currentAllowance", + "nameLocation": "1068:16:9", + "nodeType": "VariableDeclaration", + "scope": 2125, + "src": "1060:24:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2120, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1060:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2123, + "mutability": "mutable", + "name": "requestedDecrease", + "nameLocation": "1094:17:9", + "nodeType": "VariableDeclaration", + "scope": 2125, + "src": "1086:25:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2122, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1086:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1042:70:9" + }, + "src": "1004:109:9" + }, + { + "body": + { + "id": 2148, + "nodeType": "Block", + "src": "1375:88:9", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 2137, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2129, + "src": "1405:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "arguments": + [ + { + "expression": + { + "id": 2140, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2129, + "src": "1427:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 2141, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1433:8:9", + "memberName": "transfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 2066, + "src": "1427:14:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + { + "components": + [ + { + "id": 2142, + "name": "to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2131, + "src": "1444:2:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2143, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2133, + "src": "1448:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2144, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1443:11:9", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_address_$_t_uint256_$", + "typeString": "tuple(address,uint256)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + }, + { + "typeIdentifier": "t_tuple$_t_address_$_t_uint256_$", + "typeString": "tuple(address,uint256)" + } + ], + "expression": + { + "id": 2138, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "1412:3:9", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2139, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1416:10:9", + "memberName": "encodeCall", + "nodeType": "MemberAccess", + "src": "1412:14:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencodecall_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 2145, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1412:43:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 2136, + "name": "_callOptionalReturn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2339, + "src": "1385:19:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (contract IERC20,bytes memory)" + } + }, + "id": 2146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1385:71:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2147, + "nodeType": "ExpressionStatement", + "src": "1385:71:9" + } + ] + }, + "documentation": + { + "id": 2126, + "nodeType": "StructuredDocumentation", + "src": "1119:179:9", + "text": " @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n non-reverting calls are assumed to be successful." + }, + "id": 2149, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "safeTransfer", + "nameLocation": "1312:12:9", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2134, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2129, + "mutability": "mutable", + "name": "token", + "nameLocation": "1332:5:9", + "nodeType": "VariableDeclaration", + "scope": 2149, + "src": "1325:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 2128, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2127, + "name": "IERC20", + "nameLocations": + [ + "1325:6:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "1325:6:9" + }, + "referencedDeclaration": 2099, + "src": "1325:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2131, + "mutability": "mutable", + "name": "to", + "nameLocation": "1347:2:9", + "nodeType": "VariableDeclaration", + "scope": 2149, + "src": "1339:10:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2130, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1339:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2133, + "mutability": "mutable", + "name": "value", + "nameLocation": "1359:5:9", + "nodeType": "VariableDeclaration", + "scope": 2149, + "src": "1351:13:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2132, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1351:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1324:41:9" + }, + "returnParameters": + { + "id": 2135, + "nodeType": "ParameterList", + "parameters": [], + "src": "1375:0:9" + }, + "scope": 2389, + "src": "1303:160:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2175, + "nodeType": "Block", + "src": "1792:98:9", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 2163, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2153, + "src": "1822:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "arguments": + [ + { + "expression": + { + "id": 2166, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2153, + "src": "1844:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 2167, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1850:12:9", + "memberName": "transferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 2098, + "src": "1844:18:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) external returns (bool)" + } + }, + { + "components": + [ + { + "id": 2168, + "name": "from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2155, + "src": "1865:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2169, + "name": "to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2157, + "src": "1871:2:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2170, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2159, + "src": "1875:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2171, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1864:17:9", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_address_$_t_address_$_t_uint256_$", + "typeString": "tuple(address,address,uint256)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) external returns (bool)" + }, + { + "typeIdentifier": "t_tuple$_t_address_$_t_address_$_t_uint256_$", + "typeString": "tuple(address,address,uint256)" + } + ], + "expression": + { + "id": 2164, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "1829:3:9", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2165, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1833:10:9", + "memberName": "encodeCall", + "nodeType": "MemberAccess", + "src": "1829:14:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencodecall_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 2172, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1829:53:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 2162, + "name": "_callOptionalReturn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2339, + "src": "1802:19:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (contract IERC20,bytes memory)" + } + }, + "id": 2173, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1802:81:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2174, + "nodeType": "ExpressionStatement", + "src": "1802:81:9" + } + ] + }, + "documentation": + { + "id": 2150, + "nodeType": "StructuredDocumentation", + "src": "1469:228:9", + "text": " @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n calling contract. If `token` returns no value, non-reverting calls are assumed to be successful." + }, + "id": 2176, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "safeTransferFrom", + "nameLocation": "1711:16:9", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2160, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2153, + "mutability": "mutable", + "name": "token", + "nameLocation": "1735:5:9", + "nodeType": "VariableDeclaration", + "scope": 2176, + "src": "1728:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 2152, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2151, + "name": "IERC20", + "nameLocations": + [ + "1728:6:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "1728:6:9" + }, + "referencedDeclaration": 2099, + "src": "1728:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2155, + "mutability": "mutable", + "name": "from", + "nameLocation": "1750:4:9", + "nodeType": "VariableDeclaration", + "scope": 2176, + "src": "1742:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2154, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1742:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2157, + "mutability": "mutable", + "name": "to", + "nameLocation": "1764:2:9", + "nodeType": "VariableDeclaration", + "scope": 2176, + "src": "1756:10:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2156, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1756:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2159, + "mutability": "mutable", + "name": "value", + "nameLocation": "1776:5:9", + "nodeType": "VariableDeclaration", + "scope": 2176, + "src": "1768:13:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2158, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1768:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1727:55:9" + }, + "returnParameters": + { + "id": 2161, + "nodeType": "ParameterList", + "parameters": [], + "src": "1792:0:9" + }, + "scope": 2389, + "src": "1702:188:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2206, + "nodeType": "Block", + "src": "2167:139:9", + "statements": + [ + { + "assignments": + [ + 2188 + ], + "declarations": + [ + { + "constant": false, + "id": 2188, + "mutability": "mutable", + "name": "oldAllowance", + "nameLocation": "2185:12:9", + "nodeType": "VariableDeclaration", + "scope": 2206, + "src": "2177:20:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2187, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2177:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2197, + "initialValue": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 2193, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "2224:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_SafeERC20_$2389", + "typeString": "library SafeERC20" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_SafeERC20_$2389", + "typeString": "library SafeERC20" + } + ], + "id": 2192, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2216:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 2191, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2216:7:9", + "typeDescriptions": {} + } + }, + "id": 2194, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2216:13:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2195, + "name": "spender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2182, + "src": "2231:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": + { + "id": 2189, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2180, + "src": "2200:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 2190, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2206:9:9", + "memberName": "allowance", + "nodeType": "MemberAccess", + "referencedDeclaration": 2076, + "src": "2200:15:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$_t_address_$_t_address_$returns$_t_uint256_$", + "typeString": "function (address,address) view external returns (uint256)" + } + }, + "id": 2196, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2200:39:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2177:62:9" + }, + { + "expression": + { + "arguments": + [ + { + "id": 2199, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2180, + "src": "2262:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "id": 2200, + "name": "spender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2182, + "src": "2269:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2203, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2201, + "name": "oldAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2188, + "src": "2278:12:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "id": 2202, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2184, + "src": "2293:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2278:20:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2198, + "name": "forceApprove", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2297, + "src": "2249:12:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (contract IERC20,address,uint256)" + } + }, + "id": 2204, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2249:50:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2205, + "nodeType": "ExpressionStatement", + "src": "2249:50:9" + } + ] + }, + "documentation": + { + "id": 2177, + "nodeType": "StructuredDocumentation", + "src": "1896:180:9", + "text": " @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n non-reverting calls are assumed to be successful." + }, + "id": 2207, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "safeIncreaseAllowance", + "nameLocation": "2090:21:9", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2185, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2180, + "mutability": "mutable", + "name": "token", + "nameLocation": "2119:5:9", + "nodeType": "VariableDeclaration", + "scope": 2207, + "src": "2112:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 2179, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2178, + "name": "IERC20", + "nameLocations": + [ + "2112:6:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "2112:6:9" + }, + "referencedDeclaration": 2099, + "src": "2112:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2182, + "mutability": "mutable", + "name": "spender", + "nameLocation": "2134:7:9", + "nodeType": "VariableDeclaration", + "scope": 2207, + "src": "2126:15:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2181, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2126:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2184, + "mutability": "mutable", + "name": "value", + "nameLocation": "2151:5:9", + "nodeType": "VariableDeclaration", + "scope": 2207, + "src": "2143:13:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2183, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2143:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2111:46:9" + }, + "returnParameters": + { + "id": 2186, + "nodeType": "ParameterList", + "parameters": [], + "src": "2167:0:9" + }, + "scope": 2389, + "src": "2081:225:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2249, + "nodeType": "Block", + "src": "2607:370:9", + "statements": + [ + { + "id": 2248, + "nodeType": "UncheckedBlock", + "src": "2617:354:9", + "statements": + [ + { + "assignments": + [ + 2219 + ], + "declarations": + [ + { + "constant": false, + "id": 2219, + "mutability": "mutable", + "name": "currentAllowance", + "nameLocation": "2649:16:9", + "nodeType": "VariableDeclaration", + "scope": 2248, + "src": "2641:24:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2218, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2641:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2228, + "initialValue": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 2224, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "2692:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_SafeERC20_$2389", + "typeString": "library SafeERC20" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_SafeERC20_$2389", + "typeString": "library SafeERC20" + } + ], + "id": 2223, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2684:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 2222, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2684:7:9", + "typeDescriptions": {} + } + }, + "id": 2225, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2684:13:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2226, + "name": "spender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2213, + "src": "2699:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": + { + "id": 2220, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2211, + "src": "2668:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 2221, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2674:9:9", + "memberName": "allowance", + "nodeType": "MemberAccess", + "referencedDeclaration": 2076, + "src": "2668:15:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$_t_address_$_t_address_$returns$_t_uint256_$", + "typeString": "function (address,address) view external returns (uint256)" + } + }, + "id": 2227, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2668:39:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2641:66:9" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2231, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2229, + "name": "currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2219, + "src": "2725:16:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 2230, + "name": "requestedDecrease", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2215, + "src": "2744:17:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2725:36:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2239, + "nodeType": "IfStatement", + "src": "2721:160:9", + "trueBody": + { + "id": 2238, + "nodeType": "Block", + "src": "2763:118:9", + "statements": + [ + { + "errorCall": + { + "arguments": + [ + { + "id": 2233, + "name": "spender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2213, + "src": "2821:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2234, + "name": "currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2219, + "src": "2830:16:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2235, + "name": "requestedDecrease", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2215, + "src": "2848:17:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2232, + "name": "SafeERC20FailedDecreaseAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2125, + "src": "2788:32:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$_t_address_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256,uint256) pure" + } + }, + "id": 2236, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2788:78:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2237, + "nodeType": "RevertStatement", + "src": "2781:85:9" + } + ] + } + }, + { + "expression": + { + "arguments": + [ + { + "id": 2241, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2211, + "src": "2907:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "id": 2242, + "name": "spender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2213, + "src": "2914:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2245, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2243, + "name": "currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2219, + "src": "2923:16:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "id": 2244, + "name": "requestedDecrease", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2215, + "src": "2942:17:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2923:36:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2240, + "name": "forceApprove", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2297, + "src": "2894:12:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (contract IERC20,address,uint256)" + } + }, + "id": 2246, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2894:66:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2247, + "nodeType": "ExpressionStatement", + "src": "2894:66:9" + } + ] + } + ] + }, + "documentation": + { + "id": 2208, + "nodeType": "StructuredDocumentation", + "src": "2312:192:9", + "text": " @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n value, non-reverting calls are assumed to be successful." + }, + "id": 2250, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "safeDecreaseAllowance", + "nameLocation": "2518:21:9", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2216, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2211, + "mutability": "mutable", + "name": "token", + "nameLocation": "2547:5:9", + "nodeType": "VariableDeclaration", + "scope": 2250, + "src": "2540:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 2210, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2209, + "name": "IERC20", + "nameLocations": + [ + "2540:6:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "2540:6:9" + }, + "referencedDeclaration": 2099, + "src": "2540:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2213, + "mutability": "mutable", + "name": "spender", + "nameLocation": "2562:7:9", + "nodeType": "VariableDeclaration", + "scope": 2250, + "src": "2554:15:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2212, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2554:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2215, + "mutability": "mutable", + "name": "requestedDecrease", + "nameLocation": "2579:17:9", + "nodeType": "VariableDeclaration", + "scope": 2250, + "src": "2571:25:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2214, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2571:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2539:58:9" + }, + "returnParameters": + { + "id": 2217, + "nodeType": "ParameterList", + "parameters": [], + "src": "2607:0:9" + }, + "scope": 2389, + "src": "2509:468:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2296, + "nodeType": "Block", + "src": "3373:303:9", + "statements": + [ + { + "assignments": + [ + 2262 + ], + "declarations": + [ + { + "constant": false, + "id": 2262, + "mutability": "mutable", + "name": "approvalCall", + "nameLocation": "3396:12:9", + "nodeType": "VariableDeclaration", + "scope": 2296, + "src": "3383:25:9", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 2261, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3383:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 2271, + "initialValue": + { + "arguments": + [ + { + "expression": + { + "id": 2265, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2254, + "src": "3426:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 2266, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3432:7:9", + "memberName": "approve", + "nodeType": "MemberAccess", + "referencedDeclaration": 2086, + "src": "3426:13:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + { + "components": + [ + { + "id": 2267, + "name": "spender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2256, + "src": "3442:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2268, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2258, + "src": "3451:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2269, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "3441:16:9", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_address_$_t_uint256_$", + "typeString": "tuple(address,uint256)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + }, + { + "typeIdentifier": "t_tuple$_t_address_$_t_uint256_$", + "typeString": "tuple(address,uint256)" + } + ], + "expression": + { + "id": 2263, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "3411:3:9", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2264, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "3415:10:9", + "memberName": "encodeCall", + "nodeType": "MemberAccess", + "src": "3411:14:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencodecall_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 2270, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3411:47:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "3383:75:9" + }, + { + "condition": + { + "id": 2276, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "3473:45:9", + "subExpression": + { + "arguments": + [ + { + "id": 2273, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2254, + "src": "3498:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "id": 2274, + "name": "approvalCall", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2262, + "src": "3505:12:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 2272, + "name": "_callOptionalReturnBool", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2388, + "src": "3474:23:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_bytes_memory_ptr_$returns$_t_bool_$", + "typeString": "function (contract IERC20,bytes memory) returns (bool)" + } + }, + "id": 2275, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3474:44:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2295, + "nodeType": "IfStatement", + "src": "3469:201:9", + "trueBody": + { + "id": 2294, + "nodeType": "Block", + "src": "3520:150:9", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 2278, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2254, + "src": "3554:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "arguments": + [ + { + "expression": + { + "id": 2281, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2254, + "src": "3576:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "id": 2282, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3582:7:9", + "memberName": "approve", + "nodeType": "MemberAccess", + "referencedDeclaration": 2086, + "src": "3576:13:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + { + "components": + [ + { + "id": 2283, + "name": "spender", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2256, + "src": "3592:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "hexValue": "30", + "id": 2284, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3601:1:9", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "id": 2285, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "3591:12:9", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_address_$_t_rational_0_by_1_$", + "typeString": "tuple(address,int_const 0)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + }, + { + "typeIdentifier": "t_tuple$_t_address_$_t_rational_0_by_1_$", + "typeString": "tuple(address,int_const 0)" + } + ], + "expression": + { + "id": 2279, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "3561:3:9", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2280, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "3565:10:9", + "memberName": "encodeCall", + "nodeType": "MemberAccess", + "src": "3561:14:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_abiencodecall_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 2286, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3561:43:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 2277, + "name": "_callOptionalReturn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2339, + "src": "3534:19:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (contract IERC20,bytes memory)" + } + }, + "id": 2287, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3534:71:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2288, + "nodeType": "ExpressionStatement", + "src": "3534:71:9" + }, + { + "expression": + { + "arguments": + [ + { + "id": 2290, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2254, + "src": "3639:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + { + "id": 2291, + "name": "approvalCall", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2262, + "src": "3646:12:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 2289, + "name": "_callOptionalReturn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2339, + "src": "3619:19:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_IERC20_$2099_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (contract IERC20,bytes memory)" + } + }, + "id": 2292, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3619:40:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2293, + "nodeType": "ExpressionStatement", + "src": "3619:40:9" + } + ] + } + } + ] + }, + "documentation": + { + "id": 2251, + "nodeType": "StructuredDocumentation", + "src": "2983:308:9", + "text": " @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n to be set to zero before setting it to a non-zero value, such as USDT." + }, + "id": 2297, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "forceApprove", + "nameLocation": "3305:12:9", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2259, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2254, + "mutability": "mutable", + "name": "token", + "nameLocation": "3325:5:9", + "nodeType": "VariableDeclaration", + "scope": 2297, + "src": "3318:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 2253, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2252, + "name": "IERC20", + "nameLocations": + [ + "3318:6:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "3318:6:9" + }, + "referencedDeclaration": 2099, + "src": "3318:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2256, + "mutability": "mutable", + "name": "spender", + "nameLocation": "3340:7:9", + "nodeType": "VariableDeclaration", + "scope": 2297, + "src": "3332:15:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 2255, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3332:7:9", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2258, + "mutability": "mutable", + "name": "value", + "nameLocation": "3357:5:9", + "nodeType": "VariableDeclaration", + "scope": 2297, + "src": "3349:13:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2257, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3349:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3317:46:9" + }, + "returnParameters": + { + "id": 2260, + "nodeType": "ParameterList", + "parameters": [], + "src": "3373:0:9" + }, + "scope": 2389, + "src": "3296:380:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2338, + "nodeType": "Block", + "src": "4129:559:9", + "statements": + [ + { + "assignments": + [ + 2307 + ], + "declarations": + [ + { + "constant": false, + "id": 2307, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "4491:10:9", + "nodeType": "VariableDeclaration", + "scope": 2338, + "src": "4478:23:9", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 2306, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4478:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 2315, + "initialValue": + { + "arguments": + [ + { + "id": 2313, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2303, + "src": "4532:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "arguments": + [ + { + "id": 2310, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2301, + "src": "4512:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + ], + "id": 2309, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4504:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 2308, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4504:7:9", + "typeDescriptions": {} + } + }, + "id": 2311, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4504:14:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 2312, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4519:12:9", + "memberName": "functionCall", + "nodeType": "MemberAccess", + "referencedDeclaration": 3553, + "src": "4504:27:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$returns$_t_bytes_memory_ptr_$attached_to$_t_address_$", + "typeString": "function (address,bytes memory) returns (bytes memory)" + } + }, + "id": 2314, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4504:33:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4478:59:9" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2328, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2319, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 2316, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2307, + "src": "4551:10:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 2317, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4562:6:9", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "4551:17:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "hexValue": "30", + "id": 2318, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4572:1:9", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4551:22:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "id": 2327, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4577:31:9", + "subExpression": + { + "arguments": + [ + { + "id": 2322, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2307, + "src": "4589:10:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "components": + [ + { + "id": 2324, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4602:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bool_$", + "typeString": "type(bool)" + }, + "typeName": + { + "id": 2323, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4602:4:9", + "typeDescriptions": {} + } + } + ], + "id": 2325, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "4601:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bool_$", + "typeString": "type(bool)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_type$_t_bool_$", + "typeString": "type(bool)" + } + ], + "expression": + { + "id": 2320, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "4578:3:9", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2321, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "4582:6:9", + "memberName": "decode", + "nodeType": "MemberAccess", + "src": "4578:10:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_abidecode_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2326, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4578:30:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4551:57:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2337, + "nodeType": "IfStatement", + "src": "4547:135:9", + "trueBody": + { + "id": 2336, + "nodeType": "Block", + "src": "4610:72:9", + "statements": + [ + { + "errorCall": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 2332, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2301, + "src": "4664:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + ], + "id": 2331, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4656:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 2330, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4656:7:9", + "typeDescriptions": {} + } + }, + "id": 2333, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4656:14:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 2329, + "name": "SafeERC20FailedOperation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2116, + "src": "4631:24:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$_t_address_$returns$__$", + "typeString": "function (address) pure" + } + }, + "id": 2334, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4631:40:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2335, + "nodeType": "RevertStatement", + "src": "4624:47:9" + } + ] + } + } + ] + }, + "documentation": + { + "id": 2298, + "nodeType": "StructuredDocumentation", + "src": "3682:372:9", + "text": " @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n on the return value: the return value is optional (but if data is returned, it must not be false).\n @param token The token targeted by the call.\n @param data The call data (encoded using abi.encode or one of its variants)." + }, + "id": 2339, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_callOptionalReturn", + "nameLocation": "4068:19:9", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2304, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2301, + "mutability": "mutable", + "name": "token", + "nameLocation": "4095:5:9", + "nodeType": "VariableDeclaration", + "scope": 2339, + "src": "4088:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 2300, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2299, + "name": "IERC20", + "nameLocations": + [ + "4088:6:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "4088:6:9" + }, + "referencedDeclaration": 2099, + "src": "4088:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2303, + "mutability": "mutable", + "name": "data", + "nameLocation": "4115:4:9", + "nodeType": "VariableDeclaration", + "scope": 2339, + "src": "4102:17:9", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 2302, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4102:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4087:33:9" + }, + "returnParameters": + { + "id": 2305, + "nodeType": "ParameterList", + "parameters": [], + "src": "4129:0:9" + }, + "scope": 2389, + "src": "4059:629:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": + { + "id": 2387, + "nodeType": "Block", + "src": "5278:489:9", + "statements": + [ + { + "assignments": + [ + 2351, + 2353 + ], + "declarations": + [ + { + "constant": false, + "id": 2351, + "mutability": "mutable", + "name": "success", + "nameLocation": "5579:7:9", + "nodeType": "VariableDeclaration", + "scope": 2387, + "src": "5574:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2350, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5574:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2353, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "5601:10:9", + "nodeType": "VariableDeclaration", + "scope": 2387, + "src": "5588:23:9", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 2352, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "5588:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 2361, + "initialValue": + { + "arguments": + [ + { + "id": 2359, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2345, + "src": "5635:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "arguments": + [ + { + "id": 2356, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2343, + "src": "5623:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + ], + "id": 2355, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5615:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 2354, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5615:7:9", + "typeDescriptions": {} + } + }, + "id": 2357, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5615:14:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 2358, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5630:4:9", + "memberName": "call", + "nodeType": "MemberAccess", + "src": "5615:19:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "id": 2360, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5615:25:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bool,bytes memory)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5573:67:9" + }, + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2385, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2376, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2362, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2351, + "src": "5657:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2374, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2366, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 2363, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2353, + "src": "5669:10:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 2364, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5680:6:9", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "5669:17:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2365, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5690:1:9", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5669:22:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": + { + "arguments": + [ + { + "id": 2369, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2353, + "src": "5706:10:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "components": + [ + { + "id": 2371, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5719:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bool_$", + "typeString": "type(bool)" + }, + "typeName": + { + "id": 2370, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5719:4:9", + "typeDescriptions": {} + } + } + ], + "id": 2372, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "5718:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bool_$", + "typeString": "type(bool)" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_type$_t_bool_$", + "typeString": "type(bool)" + } + ], + "expression": + { + "id": 2367, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "5695:3:9", + "typeDescriptions": + { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2368, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "5699:6:9", + "memberName": "decode", + "nodeType": "MemberAccess", + "src": "5695:10:9", + "typeDescriptions": + { + "typeIdentifier": "t_function_abidecode_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2373, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5695:30:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5669:56:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 2375, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "5668:58:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5657:69:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2384, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "arguments": + [ + { + "id": 2379, + "name": "token", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2343, + "src": "5738:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + ], + "id": 2378, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5730:7:9", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 2377, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5730:7:9", + "typeDescriptions": {} + } + }, + "id": 2380, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5730:14:9", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 2381, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5745:4:9", + "memberName": "code", + "nodeType": "MemberAccess", + "src": "5730:19:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 2382, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5750:6:9", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "5730:26:9", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 2383, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5759:1:9", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5730:30:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5657:103:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 2349, + "id": 2386, + "nodeType": "Return", + "src": "5650:110:9" + } + ] + }, + "documentation": + { + "id": 2340, + "nodeType": "StructuredDocumentation", + "src": "4694:490:9", + "text": " @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n on the return value: the return value is optional (but if data is returned, it must not be false).\n @param token The token targeted by the call.\n @param data The call data (encoded using abi.encode or one of its variants).\n This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead." + }, + "id": 2388, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_callOptionalReturnBool", + "nameLocation": "5198:23:9", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2346, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2343, + "mutability": "mutable", + "name": "token", + "nameLocation": "5229:5:9", + "nodeType": "VariableDeclaration", + "scope": 2388, + "src": "5222:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + }, + "typeName": + { + "id": 2342, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2341, + "name": "IERC20", + "nameLocations": + [ + "5222:6:9" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2099, + "src": "5222:6:9" + }, + "referencedDeclaration": 2099, + "src": "5222:6:9", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_IERC20_$2099", + "typeString": "contract IERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2345, + "mutability": "mutable", + "name": "data", + "nameLocation": "5249:4:9", + "nodeType": "VariableDeclaration", + "scope": 2388, + "src": "5236:17:9", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 2344, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "5236:5:9", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "5221:33:9" + }, + "returnParameters": + { + "id": 2349, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2348, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2388, + "src": "5272:4:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2347, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5272:4:9", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "5271:6:9" + }, + "scope": 2389, + "src": "5189:578:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + } + ], + "scope": 2390, + "src": "751:5018:9", + "usedErrors": + [ + 2116, + 2125 + ], + "usedEvents": [] + } + ], + "src": "115:5655:9" + }, + "id": 9 + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol": + { + "AST": + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol", + "exportedSymbols": + { + "Address": + [ + 3732 + ] + }, + "id": 3733, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 3481, + "literals": + [ + "solidity", + "^", + "0.8", + ".20" + ], + "nodeType": "PragmaDirective", + "src": "101:24:10" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "Address", + "contractDependencies": [], + "contractKind": "library", + "documentation": + { + "id": 3482, + "nodeType": "StructuredDocumentation", + "src": "127:67:10", + "text": " @dev Collection of functions related to the address type" + }, + "fullyImplemented": true, + "id": 3732, + "linearizedBaseContracts": + [ + 3732 + ], + "name": "Address", + "nameLocation": "203:7:10", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "documentation": + { + "id": 3483, + "nodeType": "StructuredDocumentation", + "src": "217:94:10", + "text": " @dev The ETH balance of the account is not enough to perform the operation." + }, + "errorSelector": "cd786059", + "id": 3487, + "name": "AddressInsufficientBalance", + "nameLocation": "322:26:10", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 3486, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3485, + "mutability": "mutable", + "name": "account", + "nameLocation": "357:7:10", + "nodeType": "VariableDeclaration", + "scope": 3487, + "src": "349:15:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3484, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "349:7:10", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "348:17:10" + }, + "src": "316:50:10" + }, + { + "documentation": + { + "id": 3488, + "nodeType": "StructuredDocumentation", + "src": "372:75:10", + "text": " @dev There's no code at `target` (it is not a contract)." + }, + "errorSelector": "9996b315", + "id": 3492, + "name": "AddressEmptyCode", + "nameLocation": "458:16:10", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 3491, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3490, + "mutability": "mutable", + "name": "target", + "nameLocation": "483:6:10", + "nodeType": "VariableDeclaration", + "scope": 3492, + "src": "475:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3489, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "475:7:10", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "474:16:10" + }, + "src": "452:39:10" + }, + { + "documentation": + { + "id": 3493, + "nodeType": "StructuredDocumentation", + "src": "497:89:10", + "text": " @dev A call to an address target failed. The target may have reverted." + }, + "errorSelector": "1425ea42", + "id": 3495, + "name": "FailedInnerCall", + "nameLocation": "597:15:10", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 3494, + "nodeType": "ParameterList", + "parameters": [], + "src": "612:2:10" + }, + "src": "591:24:10" + }, + { + "body": + { + "id": 3535, + "nodeType": "Block", + "src": "1602:260:10", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3509, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "arguments": + [ + { + "id": 3505, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "1624:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + ], + "id": 3504, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1616:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 3503, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1616:7:10", + "typeDescriptions": {} + } + }, + "id": 3506, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1616:13:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 3507, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1630:7:10", + "memberName": "balance", + "nodeType": "MemberAccess", + "src": "1616:21:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 3508, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3500, + "src": "1640:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1616:30:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3518, + "nodeType": "IfStatement", + "src": "1612:109:10", + "trueBody": + { + "id": 3517, + "nodeType": "Block", + "src": "1648:73:10", + "statements": + [ + { + "errorCall": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 3513, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "1704:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + ], + "id": 3512, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1696:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 3511, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1696:7:10", + "typeDescriptions": {} + } + }, + "id": 3514, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1696:13:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 3510, + "name": "AddressInsufficientBalance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3487, + "src": "1669:26:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$_t_address_$returns$__$", + "typeString": "function (address) pure" + } + }, + "id": 3515, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1669:41:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 3516, + "nodeType": "RevertStatement", + "src": "1662:48:10" + } + ] + } + }, + { + "assignments": + [ + 3520, + null + ], + "declarations": + [ + { + "constant": false, + "id": 3520, + "mutability": "mutable", + "name": "success", + "nameLocation": "1737:7:10", + "nodeType": "VariableDeclaration", + "scope": 3535, + "src": "1732:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 3519, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1732:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + null + ], + "id": 3527, + "initialValue": + { + "arguments": + [ + { + "hexValue": "", + "id": 3525, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1780:2:10", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + } + ], + "expression": + { + "id": 3521, + "name": "recipient", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3498, + "src": "1750:9:10", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "id": 3522, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1760:4:10", + "memberName": "call", + "nodeType": "MemberAccess", + "src": "1750:14:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "id": 3524, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "names": + [ + "value" + ], + "nodeType": "FunctionCallOptions", + "options": + [ + { + "id": 3523, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3500, + "src": "1772:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "src": "1750:29:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "id": 3526, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1750:33:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bool,bytes memory)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1731:52:10" + }, + { + "condition": + { + "id": 3529, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "1797:8:10", + "subExpression": + { + "id": 3528, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3520, + "src": "1798:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3534, + "nodeType": "IfStatement", + "src": "1793:63:10", + "trueBody": + { + "id": 3533, + "nodeType": "Block", + "src": "1807:49:10", + "statements": + [ + { + "errorCall": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 3530, + "name": "FailedInnerCall", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3495, + "src": "1828:15:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 3531, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1828:17:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 3532, + "nodeType": "RevertStatement", + "src": "1821:24:10" + } + ] + } + } + ] + }, + "documentation": + { + "id": 3496, + "nodeType": "StructuredDocumentation", + "src": "621:905:10", + "text": " @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n `recipient`, forwarding all available gas and reverting on errors.\n https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n of certain opcodes, possibly making contracts go over the 2300 gas limit\n imposed by `transfer`, making them unable to receive funds via\n `transfer`. {sendValue} removes this limitation.\n https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n IMPORTANT: because control is transferred to `recipient`, care must be\n taken to not create reentrancy vulnerabilities. Consider using\n {ReentrancyGuard} or the\n https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]." + }, + "id": 3536, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "sendValue", + "nameLocation": "1540:9:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3501, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3498, + "mutability": "mutable", + "name": "recipient", + "nameLocation": "1566:9:10", + "nodeType": "VariableDeclaration", + "scope": 3536, + "src": "1550:25:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + }, + "typeName": + { + "id": 3497, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1550:15:10", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3500, + "mutability": "mutable", + "name": "amount", + "nameLocation": "1585:6:10", + "nodeType": "VariableDeclaration", + "scope": 3536, + "src": "1577:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3499, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1577:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1549:43:10" + }, + "returnParameters": + { + "id": 3502, + "nodeType": "ParameterList", + "parameters": [], + "src": "1602:0:10" + }, + "scope": 3732, + "src": "1531:331:10", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3552, + "nodeType": "Block", + "src": "2794:62:10", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 3547, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3539, + "src": "2833:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 3548, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3541, + "src": "2841:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "hexValue": "30", + "id": 3549, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2847:1:10", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 3546, + "name": "functionCallWithValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3599, + "src": "2811:21:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$_t_uint256_$returns$_t_bytes_memory_ptr_$", + "typeString": "function (address,bytes memory,uint256) returns (bytes memory)" + } + }, + "id": 3550, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2811:38:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "functionReturnParameters": 3545, + "id": 3551, + "nodeType": "Return", + "src": "2804:45:10" + } + ] + }, + "documentation": + { + "id": 3537, + "nodeType": "StructuredDocumentation", + "src": "1868:832:10", + "text": " @dev Performs a Solidity function call using a low level `call`. A\n plain `call` is an unsafe replacement for a function call: use this\n function instead.\n If `target` reverts with a revert reason or custom error, it is bubbled\n up by this function (like regular Solidity function calls). However, if\n the call reverted with no returned reason, this function reverts with a\n {FailedInnerCall} error.\n Returns the raw returned data. To convert to the expected return value,\n use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n Requirements:\n - `target` must be a contract.\n - calling `target` with `data` must not revert." + }, + "id": 3553, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "functionCall", + "nameLocation": "2714:12:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3542, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3539, + "mutability": "mutable", + "name": "target", + "nameLocation": "2735:6:10", + "nodeType": "VariableDeclaration", + "scope": 3553, + "src": "2727:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3538, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2727:7:10", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3541, + "mutability": "mutable", + "name": "data", + "nameLocation": "2756:4:10", + "nodeType": "VariableDeclaration", + "scope": 3553, + "src": "2743:17:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3540, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2743:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "2726:35:10" + }, + "returnParameters": + { + "id": 3545, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3544, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3553, + "src": "2780:12:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3543, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2780:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "2779:14:10" + }, + "scope": 3732, + "src": "2705:151:10", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3598, + "nodeType": "Block", + "src": "3293:279:10", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3571, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "arguments": + [ + { + "id": 3567, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "3315:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + ], + "id": 3566, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3307:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 3565, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3307:7:10", + "typeDescriptions": {} + } + }, + "id": 3568, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3307:13:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 3569, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3321:7:10", + "memberName": "balance", + "nodeType": "MemberAccess", + "src": "3307:21:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 3570, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3560, + "src": "3331:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3307:29:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3580, + "nodeType": "IfStatement", + "src": "3303:108:10", + "trueBody": + { + "id": 3579, + "nodeType": "Block", + "src": "3338:73:10", + "statements": + [ + { + "errorCall": + { + "arguments": + [ + { + "arguments": + [ + { + "id": 3575, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "3394:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_Address_$3732", + "typeString": "library Address" + } + ], + "id": 3574, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3386:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 3573, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3386:7:10", + "typeDescriptions": {} + } + }, + "id": 3576, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3386:13:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 3572, + "name": "AddressInsufficientBalance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3487, + "src": "3359:26:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$_t_address_$returns$__$", + "typeString": "function (address) pure" + } + }, + "id": 3577, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3359:41:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 3578, + "nodeType": "RevertStatement", + "src": "3352:48:10" + } + ] + } + }, + { + "assignments": + [ + 3582, + 3584 + ], + "declarations": + [ + { + "constant": false, + "id": 3582, + "mutability": "mutable", + "name": "success", + "nameLocation": "3426:7:10", + "nodeType": "VariableDeclaration", + "scope": 3598, + "src": "3421:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 3581, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3421:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3584, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "3448:10:10", + "nodeType": "VariableDeclaration", + "scope": 3598, + "src": "3435:23:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3583, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3435:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 3591, + "initialValue": + { + "arguments": + [ + { + "id": 3589, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3558, + "src": "3488:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "id": 3585, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3556, + "src": "3462:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 3586, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3469:4:10", + "memberName": "call", + "nodeType": "MemberAccess", + "src": "3462:11:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "id": 3588, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "names": + [ + "value" + ], + "nodeType": "FunctionCallOptions", + "options": + [ + { + "id": 3587, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3560, + "src": "3481:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "src": "3462:25:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "id": 3590, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3462:31:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bool,bytes memory)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "3420:73:10" + }, + { + "expression": + { + "arguments": + [ + { + "id": 3593, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3556, + "src": "3537:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 3594, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3582, + "src": "3545:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "id": 3595, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3584, + "src": "3554:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 3592, + "name": "verifyCallResultFromTarget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3691, + "src": "3510:26:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_address_$_t_bool_$_t_bytes_memory_ptr_$returns$_t_bytes_memory_ptr_$", + "typeString": "function (address,bool,bytes memory) view returns (bytes memory)" + } + }, + "id": 3596, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3510:55:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "functionReturnParameters": 3564, + "id": 3597, + "nodeType": "Return", + "src": "3503:62:10" + } + ] + }, + "documentation": + { + "id": 3554, + "nodeType": "StructuredDocumentation", + "src": "2862:313:10", + "text": " @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n but also transferring `value` wei to `target`.\n Requirements:\n - the calling contract must have an ETH balance of at least `value`.\n - the called Solidity function must be `payable`." + }, + "id": 3599, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "functionCallWithValue", + "nameLocation": "3189:21:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3561, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3556, + "mutability": "mutable", + "name": "target", + "nameLocation": "3219:6:10", + "nodeType": "VariableDeclaration", + "scope": 3599, + "src": "3211:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3555, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3211:7:10", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3558, + "mutability": "mutable", + "name": "data", + "nameLocation": "3240:4:10", + "nodeType": "VariableDeclaration", + "scope": 3599, + "src": "3227:17:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3557, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3227:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3560, + "mutability": "mutable", + "name": "value", + "nameLocation": "3254:5:10", + "nodeType": "VariableDeclaration", + "scope": 3599, + "src": "3246:13:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3559, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3246:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3210:50:10" + }, + "returnParameters": + { + "id": 3564, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3563, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3599, + "src": "3279:12:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3562, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3279:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3278:14:10" + }, + "scope": 3732, + "src": "3180:392:10", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3624, + "nodeType": "Block", + "src": "3811:154:10", + "statements": + [ + { + "assignments": + [ + 3610, + 3612 + ], + "declarations": + [ + { + "constant": false, + "id": 3610, + "mutability": "mutable", + "name": "success", + "nameLocation": "3827:7:10", + "nodeType": "VariableDeclaration", + "scope": 3624, + "src": "3822:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 3609, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3822:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3612, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "3849:10:10", + "nodeType": "VariableDeclaration", + "scope": 3624, + "src": "3836:23:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3611, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3836:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 3617, + "initialValue": + { + "arguments": + [ + { + "id": 3615, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3604, + "src": "3881:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "id": 3613, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3602, + "src": "3863:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 3614, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3870:10:10", + "memberName": "staticcall", + "nodeType": "MemberAccess", + "src": "3863:17:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_barestaticcall_view$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) view returns (bool,bytes memory)" + } + }, + "id": 3616, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3863:23:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bool,bytes memory)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "3821:65:10" + }, + { + "expression": + { + "arguments": + [ + { + "id": 3619, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3602, + "src": "3930:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 3620, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3610, + "src": "3938:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "id": 3621, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3612, + "src": "3947:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 3618, + "name": "verifyCallResultFromTarget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3691, + "src": "3903:26:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_address_$_t_bool_$_t_bytes_memory_ptr_$returns$_t_bytes_memory_ptr_$", + "typeString": "function (address,bool,bytes memory) view returns (bytes memory)" + } + }, + "id": 3622, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3903:55:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "functionReturnParameters": 3608, + "id": 3623, + "nodeType": "Return", + "src": "3896:62:10" + } + ] + }, + "documentation": + { + "id": 3600, + "nodeType": "StructuredDocumentation", + "src": "3578:128:10", + "text": " @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n but performing a static call." + }, + "id": 3625, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "functionStaticCall", + "nameLocation": "3720:18:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3605, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3602, + "mutability": "mutable", + "name": "target", + "nameLocation": "3747:6:10", + "nodeType": "VariableDeclaration", + "scope": 3625, + "src": "3739:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3601, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3739:7:10", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3604, + "mutability": "mutable", + "name": "data", + "nameLocation": "3768:4:10", + "nodeType": "VariableDeclaration", + "scope": 3625, + "src": "3755:17:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3603, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3755:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3738:35:10" + }, + "returnParameters": + { + "id": 3608, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3607, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3625, + "src": "3797:12:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3606, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3797:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3796:14:10" + }, + "scope": 3732, + "src": "3711:254:10", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3650, + "nodeType": "Block", + "src": "4203:156:10", + "statements": + [ + { + "assignments": + [ + 3636, + 3638 + ], + "declarations": + [ + { + "constant": false, + "id": 3636, + "mutability": "mutable", + "name": "success", + "nameLocation": "4219:7:10", + "nodeType": "VariableDeclaration", + "scope": 3650, + "src": "4214:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 3635, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4214:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3638, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "4241:10:10", + "nodeType": "VariableDeclaration", + "scope": 3650, + "src": "4228:23:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3637, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4228:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 3643, + "initialValue": + { + "arguments": + [ + { + "id": 3641, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3630, + "src": "4275:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": + { + "id": 3639, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3628, + "src": "4255:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 3640, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4262:12:10", + "memberName": "delegatecall", + "nodeType": "MemberAccess", + "src": "4255:19:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_baredelegatecall_nonpayable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) returns (bool,bytes memory)" + } + }, + "id": 3642, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4255:25:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bool,bytes memory)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4213:67:10" + }, + { + "expression": + { + "arguments": + [ + { + "id": 3645, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3628, + "src": "4324:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 3646, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3636, + "src": "4332:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "id": 3647, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3638, + "src": "4341:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 3644, + "name": "verifyCallResultFromTarget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3691, + "src": "4297:26:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_view$_t_address_$_t_bool_$_t_bytes_memory_ptr_$returns$_t_bytes_memory_ptr_$", + "typeString": "function (address,bool,bytes memory) view returns (bytes memory)" + } + }, + "id": 3648, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4297:55:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "functionReturnParameters": 3634, + "id": 3649, + "nodeType": "Return", + "src": "4290:62:10" + } + ] + }, + "documentation": + { + "id": 3626, + "nodeType": "StructuredDocumentation", + "src": "3971:130:10", + "text": " @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n but performing a delegate call." + }, + "id": 3651, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "functionDelegateCall", + "nameLocation": "4115:20:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3631, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3628, + "mutability": "mutable", + "name": "target", + "nameLocation": "4144:6:10", + "nodeType": "VariableDeclaration", + "scope": 3651, + "src": "4136:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3627, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4136:7:10", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3630, + "mutability": "mutable", + "name": "data", + "nameLocation": "4165:4:10", + "nodeType": "VariableDeclaration", + "scope": 3651, + "src": "4152:17:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3629, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4152:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4135:35:10" + }, + "returnParameters": + { + "id": 3634, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3633, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3651, + "src": "4189:12:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3632, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4189:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4188:14:10" + }, + "scope": 3732, + "src": "4106:253:10", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3690, + "nodeType": "Block", + "src": "4783:424:10", + "statements": + [ + { + "condition": + { + "id": 3664, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4797:8:10", + "subExpression": + { + "id": 3663, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3656, + "src": "4798:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": + { + "id": 3688, + "nodeType": "Block", + "src": "4857:344:10", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 3679, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3673, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 3670, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3658, + "src": "5045:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 3671, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5056:6:10", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "5045:17:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 3672, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5066:1:10", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5045:22:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3678, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "expression": + { + "id": 3674, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3654, + "src": "5071:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 3675, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5078:4:10", + "memberName": "code", + "nodeType": "MemberAccess", + "src": "5071:11:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 3676, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5083:6:10", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "5071:18:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 3677, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5093:1:10", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5071:23:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5045:49:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3685, + "nodeType": "IfStatement", + "src": "5041:119:10", + "trueBody": + { + "id": 3684, + "nodeType": "Block", + "src": "5096:64:10", + "statements": + [ + { + "errorCall": + { + "arguments": + [ + { + "id": 3681, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3654, + "src": "5138:6:10", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 3680, + "name": "AddressEmptyCode", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3492, + "src": "5121:16:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$_t_address_$returns$__$", + "typeString": "function (address) pure" + } + }, + "id": 3682, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5121:24:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 3683, + "nodeType": "RevertStatement", + "src": "5114:31:10" + } + ] + } + }, + { + "expression": + { + "id": 3686, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3658, + "src": "5180:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "functionReturnParameters": 3662, + "id": 3687, + "nodeType": "Return", + "src": "5173:17:10" + } + ] + }, + "id": 3689, + "nodeType": "IfStatement", + "src": "4793:408:10", + "trueBody": + { + "id": 3669, + "nodeType": "Block", + "src": "4807:44:10", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 3666, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3658, + "src": "4829:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 3665, + "name": "_revert", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3731, + "src": "4821:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes memory) pure" + } + }, + "id": 3667, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4821:19:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 3668, + "nodeType": "ExpressionStatement", + "src": "4821:19:10" + } + ] + } + } + ] + }, + "documentation": + { + "id": 3652, + "nodeType": "StructuredDocumentation", + "src": "4365:255:10", + "text": " @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\n unsuccessful call." + }, + "id": 3691, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "verifyCallResultFromTarget", + "nameLocation": "4634:26:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3659, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3654, + "mutability": "mutable", + "name": "target", + "nameLocation": "4678:6:10", + "nodeType": "VariableDeclaration", + "scope": 3691, + "src": "4670:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 3653, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4670:7:10", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3656, + "mutability": "mutable", + "name": "success", + "nameLocation": "4699:7:10", + "nodeType": "VariableDeclaration", + "scope": 3691, + "src": "4694:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 3655, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4694:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3658, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "4729:10:10", + "nodeType": "VariableDeclaration", + "scope": 3691, + "src": "4716:23:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3657, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4716:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4660:85:10" + }, + "returnParameters": + { + "id": 3662, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3661, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3691, + "src": "4769:12:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3660, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4769:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4768:14:10" + }, + "scope": 3732, + "src": "4625:582:10", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3712, + "nodeType": "Block", + "src": "5509:122:10", + "statements": + [ + { + "condition": + { + "id": 3702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "5523:8:10", + "subExpression": + { + "id": 3701, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3694, + "src": "5524:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": + { + "id": 3710, + "nodeType": "Block", + "src": "5583:42:10", + "statements": + [ + { + "expression": + { + "id": 3708, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3696, + "src": "5604:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "functionReturnParameters": 3700, + "id": 3709, + "nodeType": "Return", + "src": "5597:17:10" + } + ] + }, + "id": 3711, + "nodeType": "IfStatement", + "src": "5519:106:10", + "trueBody": + { + "id": 3707, + "nodeType": "Block", + "src": "5533:44:10", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "id": 3704, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3696, + "src": "5555:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 3703, + "name": "_revert", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3731, + "src": "5547:7:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes memory) pure" + } + }, + "id": 3705, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5547:19:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 3706, + "nodeType": "ExpressionStatement", + "src": "5547:19:10" + } + ] + } + } + ] + }, + "documentation": + { + "id": 3692, + "nodeType": "StructuredDocumentation", + "src": "5213:189:10", + "text": " @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n revert reason or with a default {FailedInnerCall} error." + }, + "id": 3713, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "verifyCallResult", + "nameLocation": "5416:16:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3697, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3694, + "mutability": "mutable", + "name": "success", + "nameLocation": "5438:7:10", + "nodeType": "VariableDeclaration", + "scope": 3713, + "src": "5433:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 3693, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5433:4:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3696, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "5460:10:10", + "nodeType": "VariableDeclaration", + "scope": 3713, + "src": "5447:23:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3695, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "5447:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "5432:39:10" + }, + "returnParameters": + { + "id": 3700, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3699, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3713, + "src": "5495:12:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3698, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "5495:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "5494:14:10" + }, + "scope": 3732, + "src": "5407:224:10", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3730, + "nodeType": "Block", + "src": "5798:461:10", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3722, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "expression": + { + "id": 3719, + "name": "returndata", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3716, + "src": "5874:10:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 3720, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5885:6:10", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "5874:17:10", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3721, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5894:1:10", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5874:21:10", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": + { + "id": 3728, + "nodeType": "Block", + "src": "6204:49:10", + "statements": + [ + { + "errorCall": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 3725, + "name": "FailedInnerCall", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3495, + "src": "6225:15:10", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 3726, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6225:17:10", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 3727, + "nodeType": "RevertStatement", + "src": "6218:24:10" + } + ] + }, + "id": 3729, + "nodeType": "IfStatement", + "src": "5870:383:10", + "trueBody": + { + "id": 3724, + "nodeType": "Block", + "src": "5897:301:10", + "statements": + [ + { + "AST": + { + "nativeSrc": "6055:133:10", + "nodeType": "YulBlock", + "src": "6055:133:10", + "statements": + [ + { + "nativeSrc": "6073:40:10", + "nodeType": "YulVariableDeclaration", + "src": "6073:40:10", + "value": + { + "arguments": + [ + { + "name": "returndata", + "nativeSrc": "6102:10:10", + "nodeType": "YulIdentifier", + "src": "6102:10:10" + } + ], + "functionName": + { + "name": "mload", + "nativeSrc": "6096:5:10", + "nodeType": "YulIdentifier", + "src": "6096:5:10" + }, + "nativeSrc": "6096:17:10", + "nodeType": "YulFunctionCall", + "src": "6096:17:10" + }, + "variables": + [ + { + "name": "returndata_size", + "nativeSrc": "6077:15:10", + "nodeType": "YulTypedName", + "src": "6077:15:10", + "type": "" + } + ] + }, + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "kind": "number", + "nativeSrc": "6141:2:10", + "nodeType": "YulLiteral", + "src": "6141:2:10", + "type": "", + "value": "32" + }, + { + "name": "returndata", + "nativeSrc": "6145:10:10", + "nodeType": "YulIdentifier", + "src": "6145:10:10" + } + ], + "functionName": + { + "name": "add", + "nativeSrc": "6137:3:10", + "nodeType": "YulIdentifier", + "src": "6137:3:10" + }, + "nativeSrc": "6137:19:10", + "nodeType": "YulFunctionCall", + "src": "6137:19:10" + }, + { + "name": "returndata_size", + "nativeSrc": "6158:15:10", + "nodeType": "YulIdentifier", + "src": "6158:15:10" + } + ], + "functionName": + { + "name": "revert", + "nativeSrc": "6130:6:10", + "nodeType": "YulIdentifier", + "src": "6130:6:10" + }, + "nativeSrc": "6130:44:10", + "nodeType": "YulFunctionCall", + "src": "6130:44:10" + }, + "nativeSrc": "6130:44:10", + "nodeType": "YulExpressionStatement", + "src": "6130:44:10" + } + ] + }, + "documentation": "@solidity memory-safe-assembly", + "evmVersion": "shanghai", + "externalReferences": + [ + { + "declaration": 3716, + "isOffset": false, + "isSlot": false, + "src": "6102:10:10", + "valueSize": 1 + }, + { + "declaration": 3716, + "isOffset": false, + "isSlot": false, + "src": "6145:10:10", + "valueSize": 1 + } + ], + "id": 3723, + "nodeType": "InlineAssembly", + "src": "6046:142:10" + } + ] + } + } + ] + }, + "documentation": + { + "id": 3714, + "nodeType": "StructuredDocumentation", + "src": "5637:101:10", + "text": " @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}." + }, + "id": 3731, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_revert", + "nameLocation": "5752:7:10", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3717, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3716, + "mutability": "mutable", + "name": "returndata", + "nameLocation": "5773:10:10", + "nodeType": "VariableDeclaration", + "scope": 3731, + "src": "5760:23:10", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": + { + "id": 3715, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "5760:5:10", + "typeDescriptions": + { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "5759:25:10" + }, + "returnParameters": + { + "id": 3718, + "nodeType": "ParameterList", + "parameters": [], + "src": "5798:0:10" + }, + "scope": 3732, + "src": "5743:516:10", + "stateMutability": "pure", + "virtual": false, + "visibility": "private" + } + ], + "scope": 3733, + "src": "195:6066:10", + "usedErrors": + [ + 3487, + 3492, + 3495 + ], + "usedEvents": [] + } + ], + "src": "101:6161:10" + }, + "id": 10 + }, + "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol": + { + "AST": + { + "absolutePath": "icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol", + "exportedSymbols": + { + "Math": + [ + 3443 + ] + }, + "id": 3444, + "license": "MIT", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 2391, + "literals": + [ + "solidity", + "^", + "0.8", + ".20" + ], + "nodeType": "PragmaDirective", + "src": "103:24:11" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "Math", + "contractDependencies": [], + "contractKind": "library", + "documentation": + { + "id": 2392, + "nodeType": "StructuredDocumentation", + "src": "129:73:11", + "text": " @dev Standard math utilities missing in the Solidity language." + }, + "fullyImplemented": true, + "id": 3443, + "linearizedBaseContracts": + [ + 3443 + ], + "name": "Math", + "nameLocation": "211:4:11", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "documentation": + { + "id": 2393, + "nodeType": "StructuredDocumentation", + "src": "222:50:11", + "text": " @dev Muldiv operation overflow." + }, + "errorSelector": "227bc153", + "id": 2395, + "name": "MathOverflowedMulDiv", + "nameLocation": "283:20:11", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 2394, + "nodeType": "ParameterList", + "parameters": [], + "src": "303:2:11" + }, + "src": "277:29:11" + }, + { + "canonicalName": "Math.Rounding", + "id": 2400, + "members": + [ + { + "id": 2396, + "name": "Floor", + "nameLocation": "336:5:11", + "nodeType": "EnumValue", + "src": "336:5:11" + }, + { + "id": 2397, + "name": "Ceil", + "nameLocation": "379:4:11", + "nodeType": "EnumValue", + "src": "379:4:11" + }, + { + "id": 2398, + "name": "Trunc", + "nameLocation": "421:5:11", + "nodeType": "EnumValue", + "src": "421:5:11" + }, + { + "id": 2399, + "name": "Expand", + "nameLocation": "451:6:11", + "nodeType": "EnumValue", + "src": "451:6:11" + } + ], + "name": "Rounding", + "nameLocation": "317:8:11", + "nodeType": "EnumDefinition", + "src": "312:169:11" + }, + { + "body": + { + "id": 2431, + "nodeType": "Block", + "src": "661:140:11", + "statements": + [ + { + "id": 2430, + "nodeType": "UncheckedBlock", + "src": "671:124:11", + "statements": + [ + { + "assignments": + [ + 2413 + ], + "declarations": + [ + { + "constant": false, + "id": 2413, + "mutability": "mutable", + "name": "c", + "nameLocation": "703:1:11", + "nodeType": "VariableDeclaration", + "scope": 2430, + "src": "695:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2412, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "695:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2417, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2416, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2414, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2403, + "src": "707:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "id": 2415, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2405, + "src": "711:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "707:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "695:17:11" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2420, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2418, + "name": "c", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2413, + "src": "730:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 2419, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2403, + "src": "734:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "730:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2425, + "nodeType": "IfStatement", + "src": "726:28:11", + "trueBody": + { + "expression": + { + "components": + [ + { + "hexValue": "66616c7365", + "id": 2421, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "745:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + { + "hexValue": "30", + "id": 2422, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "752:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "id": 2423, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "744:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_rational_0_by_1_$", + "typeString": "tuple(bool,int_const 0)" + } + }, + "functionReturnParameters": 2411, + "id": 2424, + "nodeType": "Return", + "src": "737:17:11" + } + }, + { + "expression": + { + "components": + [ + { + "hexValue": "74727565", + "id": 2426, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "776:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + { + "id": 2427, + "name": "c", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2413, + "src": "782:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2428, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "775:9:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_uint256_$", + "typeString": "tuple(bool,uint256)" + } + }, + "functionReturnParameters": 2411, + "id": 2429, + "nodeType": "Return", + "src": "768:16:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2401, + "nodeType": "StructuredDocumentation", + "src": "487:93:11", + "text": " @dev Returns the addition of two unsigned integers, with an overflow flag." + }, + "id": 2432, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "tryAdd", + "nameLocation": "594:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2406, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2403, + "mutability": "mutable", + "name": "a", + "nameLocation": "609:1:11", + "nodeType": "VariableDeclaration", + "scope": 2432, + "src": "601:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2402, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "601:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2405, + "mutability": "mutable", + "name": "b", + "nameLocation": "620:1:11", + "nodeType": "VariableDeclaration", + "scope": 2432, + "src": "612:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2404, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "612:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "600:22:11" + }, + "returnParameters": + { + "id": 2411, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2408, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2432, + "src": "646:4:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2407, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "646:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2410, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2432, + "src": "652:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2409, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "652:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "645:15:11" + }, + "scope": 3443, + "src": "585:216:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2459, + "nodeType": "Block", + "src": "984:113:11", + "statements": + [ + { + "id": 2458, + "nodeType": "UncheckedBlock", + "src": "994:97:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2446, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2444, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2437, + "src": "1022:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "id": 2445, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2435, + "src": "1026:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1022:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2451, + "nodeType": "IfStatement", + "src": "1018:28:11", + "trueBody": + { + "expression": + { + "components": + [ + { + "hexValue": "66616c7365", + "id": 2447, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1037:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + { + "hexValue": "30", + "id": 2448, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1044:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "id": 2449, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1036:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_rational_0_by_1_$", + "typeString": "tuple(bool,int_const 0)" + } + }, + "functionReturnParameters": 2443, + "id": 2450, + "nodeType": "Return", + "src": "1029:17:11" + } + }, + { + "expression": + { + "components": + [ + { + "hexValue": "74727565", + "id": 2452, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1068:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2455, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2453, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2435, + "src": "1074:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "id": 2454, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2437, + "src": "1078:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1074:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2456, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1067:13:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_uint256_$", + "typeString": "tuple(bool,uint256)" + } + }, + "functionReturnParameters": 2443, + "id": 2457, + "nodeType": "Return", + "src": "1060:20:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2433, + "nodeType": "StructuredDocumentation", + "src": "807:96:11", + "text": " @dev Returns the subtraction of two unsigned integers, with an overflow flag." + }, + "id": 2460, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "trySub", + "nameLocation": "917:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2438, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2435, + "mutability": "mutable", + "name": "a", + "nameLocation": "932:1:11", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "924:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2434, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "924:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2437, + "mutability": "mutable", + "name": "b", + "nameLocation": "943:1:11", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "935:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2436, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "935:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "923:22:11" + }, + "returnParameters": + { + "id": 2443, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2440, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "969:4:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2439, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "969:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2442, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "975:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2441, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "975:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "968:15:11" + }, + "scope": 3443, + "src": "908:189:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2501, + "nodeType": "Block", + "src": "1283:417:11", + "statements": + [ + { + "id": 2500, + "nodeType": "UncheckedBlock", + "src": "1293:401:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2474, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2472, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2463, + "src": "1551:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2473, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1556:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "1551:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2479, + "nodeType": "IfStatement", + "src": "1547:28:11", + "trueBody": + { + "expression": + { + "components": + [ + { + "hexValue": "74727565", + "id": 2475, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1567:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + { + "hexValue": "30", + "id": 2476, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1573:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "id": 2477, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1566:9:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_rational_0_by_1_$", + "typeString": "tuple(bool,int_const 0)" + } + }, + "functionReturnParameters": 2471, + "id": 2478, + "nodeType": "Return", + "src": "1559:16:11" + } + }, + { + "assignments": + [ + 2481 + ], + "declarations": + [ + { + "constant": false, + "id": 2481, + "mutability": "mutable", + "name": "c", + "nameLocation": "1597:1:11", + "nodeType": "VariableDeclaration", + "scope": 2500, + "src": "1589:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2480, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1589:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2485, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2484, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2482, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2463, + "src": "1601:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2483, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2465, + "src": "1605:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1601:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1589:17:11" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2490, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2488, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2486, + "name": "c", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2481, + "src": "1624:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2487, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2463, + "src": "1628:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1624:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": + { + "id": 2489, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2465, + "src": "1633:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1624:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2495, + "nodeType": "IfStatement", + "src": "1620:33:11", + "trueBody": + { + "expression": + { + "components": + [ + { + "hexValue": "66616c7365", + "id": 2491, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1644:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + { + "hexValue": "30", + "id": 2492, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1651:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "id": 2493, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1643:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_rational_0_by_1_$", + "typeString": "tuple(bool,int_const 0)" + } + }, + "functionReturnParameters": 2471, + "id": 2494, + "nodeType": "Return", + "src": "1636:17:11" + } + }, + { + "expression": + { + "components": + [ + { + "hexValue": "74727565", + "id": 2496, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1675:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + { + "id": 2497, + "name": "c", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2481, + "src": "1681:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2498, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1674:9:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_uint256_$", + "typeString": "tuple(bool,uint256)" + } + }, + "functionReturnParameters": 2471, + "id": 2499, + "nodeType": "Return", + "src": "1667:16:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2461, + "nodeType": "StructuredDocumentation", + "src": "1103:99:11", + "text": " @dev Returns the multiplication of two unsigned integers, with an overflow flag." + }, + "id": 2502, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "tryMul", + "nameLocation": "1216:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2466, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2463, + "mutability": "mutable", + "name": "a", + "nameLocation": "1231:1:11", + "nodeType": "VariableDeclaration", + "scope": 2502, + "src": "1223:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2462, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1223:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2465, + "mutability": "mutable", + "name": "b", + "nameLocation": "1242:1:11", + "nodeType": "VariableDeclaration", + "scope": 2502, + "src": "1234:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2464, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1234:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1222:22:11" + }, + "returnParameters": + { + "id": 2471, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2468, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2502, + "src": "1268:4:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2467, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1268:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2470, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2502, + "src": "1274:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2469, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1274:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1267:15:11" + }, + "scope": 3443, + "src": "1207:493:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2529, + "nodeType": "Block", + "src": "1887:114:11", + "statements": + [ + { + "id": 2528, + "nodeType": "UncheckedBlock", + "src": "1897:98:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2516, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2514, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2507, + "src": "1925:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2515, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1930:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "1925:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2521, + "nodeType": "IfStatement", + "src": "1921:29:11", + "trueBody": + { + "expression": + { + "components": + [ + { + "hexValue": "66616c7365", + "id": 2517, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1941:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + { + "hexValue": "30", + "id": 2518, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1948:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "id": 2519, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1940:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_rational_0_by_1_$", + "typeString": "tuple(bool,int_const 0)" + } + }, + "functionReturnParameters": 2513, + "id": 2520, + "nodeType": "Return", + "src": "1933:17:11" + } + }, + { + "expression": + { + "components": + [ + { + "hexValue": "74727565", + "id": 2522, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1972:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2525, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2523, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2505, + "src": "1978:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2524, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2507, + "src": "1982:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1978:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2526, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1971:13:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_uint256_$", + "typeString": "tuple(bool,uint256)" + } + }, + "functionReturnParameters": 2513, + "id": 2527, + "nodeType": "Return", + "src": "1964:20:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2503, + "nodeType": "StructuredDocumentation", + "src": "1706:100:11", + "text": " @dev Returns the division of two unsigned integers, with a division by zero flag." + }, + "id": 2530, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "tryDiv", + "nameLocation": "1820:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2508, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2505, + "mutability": "mutable", + "name": "a", + "nameLocation": "1835:1:11", + "nodeType": "VariableDeclaration", + "scope": 2530, + "src": "1827:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2504, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1827:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2507, + "mutability": "mutable", + "name": "b", + "nameLocation": "1846:1:11", + "nodeType": "VariableDeclaration", + "scope": 2530, + "src": "1838:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2506, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1838:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1826:22:11" + }, + "returnParameters": + { + "id": 2513, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2510, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2530, + "src": "1872:4:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2509, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1872:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2512, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2530, + "src": "1878:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2511, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1878:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1871:15:11" + }, + "scope": 3443, + "src": "1811:190:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2557, + "nodeType": "Block", + "src": "2198:114:11", + "statements": + [ + { + "id": 2556, + "nodeType": "UncheckedBlock", + "src": "2208:98:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2544, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2542, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2535, + "src": "2236:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2543, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2241:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "2236:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2549, + "nodeType": "IfStatement", + "src": "2232:29:11", + "trueBody": + { + "expression": + { + "components": + [ + { + "hexValue": "66616c7365", + "id": 2545, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2252:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + { + "hexValue": "30", + "id": 2546, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2259:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "id": 2547, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "2251:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_rational_0_by_1_$", + "typeString": "tuple(bool,int_const 0)" + } + }, + "functionReturnParameters": 2541, + "id": 2548, + "nodeType": "Return", + "src": "2244:17:11" + } + }, + { + "expression": + { + "components": + [ + { + "hexValue": "74727565", + "id": 2550, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2283:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2553, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2551, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2533, + "src": "2289:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "%", + "rightExpression": + { + "id": 2552, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2535, + "src": "2293:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2289:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2554, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "2282:13:11", + "typeDescriptions": + { + "typeIdentifier": "t_tuple$_t_bool_$_t_uint256_$", + "typeString": "tuple(bool,uint256)" + } + }, + "functionReturnParameters": 2541, + "id": 2555, + "nodeType": "Return", + "src": "2275:20:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2531, + "nodeType": "StructuredDocumentation", + "src": "2007:110:11", + "text": " @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag." + }, + "id": 2558, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "tryMod", + "nameLocation": "2131:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2536, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2533, + "mutability": "mutable", + "name": "a", + "nameLocation": "2146:1:11", + "nodeType": "VariableDeclaration", + "scope": 2558, + "src": "2138:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2532, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2138:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2535, + "mutability": "mutable", + "name": "b", + "nameLocation": "2157:1:11", + "nodeType": "VariableDeclaration", + "scope": 2558, + "src": "2149:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2534, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2149:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2137:22:11" + }, + "returnParameters": + { + "id": 2541, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2538, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2558, + "src": "2183:4:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 2537, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2183:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2540, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2558, + "src": "2189:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2539, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2189:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2182:15:11" + }, + "scope": 3443, + "src": "2122:190:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2575, + "nodeType": "Block", + "src": "2449:37:11", + "statements": + [ + { + "expression": + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2570, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2568, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2561, + "src": "2466:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "id": 2569, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2563, + "src": "2470:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2466:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": + { + "id": 2572, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2563, + "src": "2478:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2573, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "2466:13:11", + "trueExpression": + { + "id": 2571, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2561, + "src": "2474:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2567, + "id": 2574, + "nodeType": "Return", + "src": "2459:20:11" + } + ] + }, + "documentation": + { + "id": 2559, + "nodeType": "StructuredDocumentation", + "src": "2318:59:11", + "text": " @dev Returns the largest of two numbers." + }, + "id": 2576, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "max", + "nameLocation": "2391:3:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2564, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2561, + "mutability": "mutable", + "name": "a", + "nameLocation": "2403:1:11", + "nodeType": "VariableDeclaration", + "scope": 2576, + "src": "2395:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2560, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2395:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2563, + "mutability": "mutable", + "name": "b", + "nameLocation": "2414:1:11", + "nodeType": "VariableDeclaration", + "scope": 2576, + "src": "2406:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2562, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2406:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2394:22:11" + }, + "returnParameters": + { + "id": 2567, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2566, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2576, + "src": "2440:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2565, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2440:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2439:9:11" + }, + "scope": 3443, + "src": "2382:104:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2593, + "nodeType": "Block", + "src": "2624:37:11", + "statements": + [ + { + "expression": + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2588, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2586, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2579, + "src": "2641:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 2587, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2581, + "src": "2645:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2641:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": + { + "id": 2590, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2581, + "src": "2653:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2591, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "2641:13:11", + "trueExpression": + { + "id": 2589, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2579, + "src": "2649:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2585, + "id": 2592, + "nodeType": "Return", + "src": "2634:20:11" + } + ] + }, + "documentation": + { + "id": 2577, + "nodeType": "StructuredDocumentation", + "src": "2492:60:11", + "text": " @dev Returns the smallest of two numbers." + }, + "id": 2594, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "min", + "nameLocation": "2566:3:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2582, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2579, + "mutability": "mutable", + "name": "a", + "nameLocation": "2578:1:11", + "nodeType": "VariableDeclaration", + "scope": 2594, + "src": "2570:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2578, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2570:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2581, + "mutability": "mutable", + "name": "b", + "nameLocation": "2589:1:11", + "nodeType": "VariableDeclaration", + "scope": 2594, + "src": "2581:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2580, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2581:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2569:22:11" + }, + "returnParameters": + { + "id": 2585, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2584, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2594, + "src": "2615:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2583, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2615:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2614:9:11" + }, + "scope": 3443, + "src": "2557:104:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2616, + "nodeType": "Block", + "src": "2845:82:11", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2614, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2606, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2604, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2597, + "src": "2900:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "&", + "rightExpression": + { + "id": 2605, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2599, + "src": "2904:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2900:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2607, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "2899:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2613, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2610, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2608, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2597, + "src": "2910:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "^", + "rightExpression": + { + "id": 2609, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2599, + "src": "2914:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2910:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2611, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "2909:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "hexValue": "32", + "id": 2612, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2919:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "2909:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2899:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2603, + "id": 2615, + "nodeType": "Return", + "src": "2892:28:11" + } + ] + }, + "documentation": + { + "id": 2595, + "nodeType": "StructuredDocumentation", + "src": "2667:102:11", + "text": " @dev Returns the average of two numbers. The result is rounded towards\n zero." + }, + "id": 2617, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "average", + "nameLocation": "2783:7:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2600, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2597, + "mutability": "mutable", + "name": "a", + "nameLocation": "2799:1:11", + "nodeType": "VariableDeclaration", + "scope": 2617, + "src": "2791:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2596, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2791:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2599, + "mutability": "mutable", + "name": "b", + "nameLocation": "2810:1:11", + "nodeType": "VariableDeclaration", + "scope": 2617, + "src": "2802:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2598, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2802:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2790:22:11" + }, + "returnParameters": + { + "id": 2603, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2602, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2617, + "src": "2836:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2601, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2836:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2835:9:11" + }, + "scope": 3443, + "src": "2774:153:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2650, + "nodeType": "Block", + "src": "3219:260:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2629, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2627, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2622, + "src": "3233:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3238:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "3233:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2635, + "nodeType": "IfStatement", + "src": "3229:127:11", + "trueBody": + { + "id": 2634, + "nodeType": "Block", + "src": "3241:115:11", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2632, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2630, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2620, + "src": "3340:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2631, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2622, + "src": "3344:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3340:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2626, + "id": 2633, + "nodeType": "Return", + "src": "3333:12:11" + } + ] + } + }, + { + "expression": + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2638, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2636, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2620, + "src": "3444:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2637, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3449:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "3444:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2647, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2645, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2642, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2640, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2620, + "src": "3458:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "hexValue": "31", + "id": 2641, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3462:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "3458:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2643, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "3457:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2644, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2622, + "src": "3467:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3457:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "hexValue": "31", + "id": 2646, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3471:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "3457:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2648, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "3444:28:11", + "trueExpression": + { + "hexValue": "30", + "id": 2639, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3453:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2626, + "id": 2649, + "nodeType": "Return", + "src": "3437:35:11" + } + ] + }, + "documentation": + { + "id": 2618, + "nodeType": "StructuredDocumentation", + "src": "2933:210:11", + "text": " @dev Returns the ceiling of the division of two numbers.\n This differs from standard division with `/` in that it rounds towards infinity instead\n of rounding towards zero." + }, + "id": 2651, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "ceilDiv", + "nameLocation": "3157:7:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2623, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2620, + "mutability": "mutable", + "name": "a", + "nameLocation": "3173:1:11", + "nodeType": "VariableDeclaration", + "scope": 2651, + "src": "3165:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2619, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3165:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2622, + "mutability": "mutable", + "name": "b", + "nameLocation": "3184:1:11", + "nodeType": "VariableDeclaration", + "scope": 2651, + "src": "3176:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2621, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3176:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3164:22:11" + }, + "returnParameters": + { + "id": 2626, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2625, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2651, + "src": "3210:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2624, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3210:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3209:9:11" + }, + "scope": 3443, + "src": "3148:331:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2776, + "nodeType": "Block", + "src": "3901:4018:11", + "statements": + [ + { + "id": 2775, + "nodeType": "UncheckedBlock", + "src": "3911:4002:11", + "statements": + [ + { + "assignments": + [ + 2664 + ], + "declarations": + [ + { + "constant": false, + "id": 2664, + "mutability": "mutable", + "name": "prod0", + "nameLocation": "4240:5:11", + "nodeType": "VariableDeclaration", + "scope": 2775, + "src": "4232:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2663, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4232:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2668, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2667, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2665, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2654, + "src": "4248:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2666, + "name": "y", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2656, + "src": "4252:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4248:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4232:21:11" + }, + { + "assignments": + [ + 2670 + ], + "declarations": + [ + { + "constant": false, + "id": 2670, + "mutability": "mutable", + "name": "prod1", + "nameLocation": "4320:5:11", + "nodeType": "VariableDeclaration", + "scope": 2775, + "src": "4312:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2669, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4312:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2671, + "nodeType": "VariableDeclarationStatement", + "src": "4312:13:11" + }, + { + "AST": + { + "nativeSrc": "4392:122:11", + "nodeType": "YulBlock", + "src": "4392:122:11", + "statements": + [ + { + "nativeSrc": "4410:30:11", + "nodeType": "YulVariableDeclaration", + "src": "4410:30:11", + "value": + { + "arguments": + [ + { + "name": "x", + "nativeSrc": "4427:1:11", + "nodeType": "YulIdentifier", + "src": "4427:1:11" + }, + { + "name": "y", + "nativeSrc": "4430:1:11", + "nodeType": "YulIdentifier", + "src": "4430:1:11" + }, + { + "arguments": + [ + { + "kind": "number", + "nativeSrc": "4437:1:11", + "nodeType": "YulLiteral", + "src": "4437:1:11", + "type": "", + "value": "0" + } + ], + "functionName": + { + "name": "not", + "nativeSrc": "4433:3:11", + "nodeType": "YulIdentifier", + "src": "4433:3:11" + }, + "nativeSrc": "4433:6:11", + "nodeType": "YulFunctionCall", + "src": "4433:6:11" + } + ], + "functionName": + { + "name": "mulmod", + "nativeSrc": "4420:6:11", + "nodeType": "YulIdentifier", + "src": "4420:6:11" + }, + "nativeSrc": "4420:20:11", + "nodeType": "YulFunctionCall", + "src": "4420:20:11" + }, + "variables": + [ + { + "name": "mm", + "nativeSrc": "4414:2:11", + "nodeType": "YulTypedName", + "src": "4414:2:11", + "type": "" + } + ] + }, + { + "nativeSrc": "4457:43:11", + "nodeType": "YulAssignment", + "src": "4457:43:11", + "value": + { + "arguments": + [ + { + "arguments": + [ + { + "name": "mm", + "nativeSrc": "4474:2:11", + "nodeType": "YulIdentifier", + "src": "4474:2:11" + }, + { + "name": "prod0", + "nativeSrc": "4478:5:11", + "nodeType": "YulIdentifier", + "src": "4478:5:11" + } + ], + "functionName": + { + "name": "sub", + "nativeSrc": "4470:3:11", + "nodeType": "YulIdentifier", + "src": "4470:3:11" + }, + "nativeSrc": "4470:14:11", + "nodeType": "YulFunctionCall", + "src": "4470:14:11" + }, + { + "arguments": + [ + { + "name": "mm", + "nativeSrc": "4489:2:11", + "nodeType": "YulIdentifier", + "src": "4489:2:11" + }, + { + "name": "prod0", + "nativeSrc": "4493:5:11", + "nodeType": "YulIdentifier", + "src": "4493:5:11" + } + ], + "functionName": + { + "name": "lt", + "nativeSrc": "4486:2:11", + "nodeType": "YulIdentifier", + "src": "4486:2:11" + }, + "nativeSrc": "4486:13:11", + "nodeType": "YulFunctionCall", + "src": "4486:13:11" + } + ], + "functionName": + { + "name": "sub", + "nativeSrc": "4466:3:11", + "nodeType": "YulIdentifier", + "src": "4466:3:11" + }, + "nativeSrc": "4466:34:11", + "nodeType": "YulFunctionCall", + "src": "4466:34:11" + }, + "variableNames": + [ + { + "name": "prod1", + "nativeSrc": "4457:5:11", + "nodeType": "YulIdentifier", + "src": "4457:5:11" + } + ] + } + ] + }, + "evmVersion": "shanghai", + "externalReferences": + [ + { + "declaration": 2664, + "isOffset": false, + "isSlot": false, + "src": "4478:5:11", + "valueSize": 1 + }, + { + "declaration": 2664, + "isOffset": false, + "isSlot": false, + "src": "4493:5:11", + "valueSize": 1 + }, + { + "declaration": 2670, + "isOffset": false, + "isSlot": false, + "src": "4457:5:11", + "valueSize": 1 + }, + { + "declaration": 2654, + "isOffset": false, + "isSlot": false, + "src": "4427:1:11", + "valueSize": 1 + }, + { + "declaration": 2656, + "isOffset": false, + "isSlot": false, + "src": "4430:1:11", + "valueSize": 1 + } + ], + "id": 2672, + "nodeType": "InlineAssembly", + "src": "4383:131:11" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2675, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2673, + "name": "prod1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2670, + "src": "4595:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2674, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4604:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4595:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2681, + "nodeType": "IfStatement", + "src": "4591:368:11", + "trueBody": + { + "id": 2680, + "nodeType": "Block", + "src": "4607:352:11", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2678, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2676, + "name": "prod0", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2664, + "src": "4925:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2677, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "4933:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4925:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2662, + "id": 2679, + "nodeType": "Return", + "src": "4918:26:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2684, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2682, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "5065:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": + { + "id": 2683, + "name": "prod1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2670, + "src": "5080:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5065:20:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2689, + "nodeType": "IfStatement", + "src": "5061:88:11", + "trueBody": + { + "id": 2688, + "nodeType": "Block", + "src": "5087:62:11", + "statements": + [ + { + "errorCall": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 2685, + "name": "MathOverflowedMulDiv", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2395, + "src": "5112:20:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2686, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5112:22:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2687, + "nodeType": "RevertStatement", + "src": "5105:29:11" + } + ] + } + }, + { + "assignments": + [ + 2691 + ], + "declarations": + [ + { + "constant": false, + "id": 2691, + "mutability": "mutable", + "name": "remainder", + "nameLocation": "5412:9:11", + "nodeType": "VariableDeclaration", + "scope": 2775, + "src": "5404:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2690, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5404:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2692, + "nodeType": "VariableDeclarationStatement", + "src": "5404:17:11" + }, + { + "AST": + { + "nativeSrc": "5444:291:11", + "nodeType": "YulBlock", + "src": "5444:291:11", + "statements": + [ + { + "nativeSrc": "5513:38:11", + "nodeType": "YulAssignment", + "src": "5513:38:11", + "value": + { + "arguments": + [ + { + "name": "x", + "nativeSrc": "5533:1:11", + "nodeType": "YulIdentifier", + "src": "5533:1:11" + }, + { + "name": "y", + "nativeSrc": "5536:1:11", + "nodeType": "YulIdentifier", + "src": "5536:1:11" + }, + { + "name": "denominator", + "nativeSrc": "5539:11:11", + "nodeType": "YulIdentifier", + "src": "5539:11:11" + } + ], + "functionName": + { + "name": "mulmod", + "nativeSrc": "5526:6:11", + "nodeType": "YulIdentifier", + "src": "5526:6:11" + }, + "nativeSrc": "5526:25:11", + "nodeType": "YulFunctionCall", + "src": "5526:25:11" + }, + "variableNames": + [ + { + "name": "remainder", + "nativeSrc": "5513:9:11", + "nodeType": "YulIdentifier", + "src": "5513:9:11" + } + ] + }, + { + "nativeSrc": "5633:41:11", + "nodeType": "YulAssignment", + "src": "5633:41:11", + "value": + { + "arguments": + [ + { + "name": "prod1", + "nativeSrc": "5646:5:11", + "nodeType": "YulIdentifier", + "src": "5646:5:11" + }, + { + "arguments": + [ + { + "name": "remainder", + "nativeSrc": "5656:9:11", + "nodeType": "YulIdentifier", + "src": "5656:9:11" + }, + { + "name": "prod0", + "nativeSrc": "5667:5:11", + "nodeType": "YulIdentifier", + "src": "5667:5:11" + } + ], + "functionName": + { + "name": "gt", + "nativeSrc": "5653:2:11", + "nodeType": "YulIdentifier", + "src": "5653:2:11" + }, + "nativeSrc": "5653:20:11", + "nodeType": "YulFunctionCall", + "src": "5653:20:11" + } + ], + "functionName": + { + "name": "sub", + "nativeSrc": "5642:3:11", + "nodeType": "YulIdentifier", + "src": "5642:3:11" + }, + "nativeSrc": "5642:32:11", + "nodeType": "YulFunctionCall", + "src": "5642:32:11" + }, + "variableNames": + [ + { + "name": "prod1", + "nativeSrc": "5633:5:11", + "nodeType": "YulIdentifier", + "src": "5633:5:11" + } + ] + }, + { + "nativeSrc": "5691:30:11", + "nodeType": "YulAssignment", + "src": "5691:30:11", + "value": + { + "arguments": + [ + { + "name": "prod0", + "nativeSrc": "5704:5:11", + "nodeType": "YulIdentifier", + "src": "5704:5:11" + }, + { + "name": "remainder", + "nativeSrc": "5711:9:11", + "nodeType": "YulIdentifier", + "src": "5711:9:11" + } + ], + "functionName": + { + "name": "sub", + "nativeSrc": "5700:3:11", + "nodeType": "YulIdentifier", + "src": "5700:3:11" + }, + "nativeSrc": "5700:21:11", + "nodeType": "YulFunctionCall", + "src": "5700:21:11" + }, + "variableNames": + [ + { + "name": "prod0", + "nativeSrc": "5691:5:11", + "nodeType": "YulIdentifier", + "src": "5691:5:11" + } + ] + } + ] + }, + "evmVersion": "shanghai", + "externalReferences": + [ + { + "declaration": 2658, + "isOffset": false, + "isSlot": false, + "src": "5539:11:11", + "valueSize": 1 + }, + { + "declaration": 2664, + "isOffset": false, + "isSlot": false, + "src": "5667:5:11", + "valueSize": 1 + }, + { + "declaration": 2664, + "isOffset": false, + "isSlot": false, + "src": "5691:5:11", + "valueSize": 1 + }, + { + "declaration": 2664, + "isOffset": false, + "isSlot": false, + "src": "5704:5:11", + "valueSize": 1 + }, + { + "declaration": 2670, + "isOffset": false, + "isSlot": false, + "src": "5633:5:11", + "valueSize": 1 + }, + { + "declaration": 2670, + "isOffset": false, + "isSlot": false, + "src": "5646:5:11", + "valueSize": 1 + }, + { + "declaration": 2691, + "isOffset": false, + "isSlot": false, + "src": "5513:9:11", + "valueSize": 1 + }, + { + "declaration": 2691, + "isOffset": false, + "isSlot": false, + "src": "5656:9:11", + "valueSize": 1 + }, + { + "declaration": 2691, + "isOffset": false, + "isSlot": false, + "src": "5711:9:11", + "valueSize": 1 + }, + { + "declaration": 2654, + "isOffset": false, + "isSlot": false, + "src": "5533:1:11", + "valueSize": 1 + }, + { + "declaration": 2656, + "isOffset": false, + "isSlot": false, + "src": "5536:1:11", + "valueSize": 1 + } + ], + "id": 2693, + "nodeType": "InlineAssembly", + "src": "5435:300:11" + }, + { + "assignments": + [ + 2695 + ], + "declarations": + [ + { + "constant": false, + "id": 2695, + "mutability": "mutable", + "name": "twos", + "nameLocation": "5947:4:11", + "nodeType": "VariableDeclaration", + "scope": 2775, + "src": "5939:12:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2694, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5939:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2702, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2701, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2696, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "5954:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "&", + "rightExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2699, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "30", + "id": 2697, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5969:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "id": 2698, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "5973:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5969:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2700, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "5968:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5954:31:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5939:46:11" + }, + { + "AST": + { + "nativeSrc": "6008:362:11", + "nodeType": "YulBlock", + "src": "6008:362:11", + "statements": + [ + { + "nativeSrc": "6073:37:11", + "nodeType": "YulAssignment", + "src": "6073:37:11", + "value": + { + "arguments": + [ + { + "name": "denominator", + "nativeSrc": "6092:11:11", + "nodeType": "YulIdentifier", + "src": "6092:11:11" + }, + { + "name": "twos", + "nativeSrc": "6105:4:11", + "nodeType": "YulIdentifier", + "src": "6105:4:11" + } + ], + "functionName": + { + "name": "div", + "nativeSrc": "6088:3:11", + "nodeType": "YulIdentifier", + "src": "6088:3:11" + }, + "nativeSrc": "6088:22:11", + "nodeType": "YulFunctionCall", + "src": "6088:22:11" + }, + "variableNames": + [ + { + "name": "denominator", + "nativeSrc": "6073:11:11", + "nodeType": "YulIdentifier", + "src": "6073:11:11" + } + ] + }, + { + "nativeSrc": "6177:25:11", + "nodeType": "YulAssignment", + "src": "6177:25:11", + "value": + { + "arguments": + [ + { + "name": "prod0", + "nativeSrc": "6190:5:11", + "nodeType": "YulIdentifier", + "src": "6190:5:11" + }, + { + "name": "twos", + "nativeSrc": "6197:4:11", + "nodeType": "YulIdentifier", + "src": "6197:4:11" + } + ], + "functionName": + { + "name": "div", + "nativeSrc": "6186:3:11", + "nodeType": "YulIdentifier", + "src": "6186:3:11" + }, + "nativeSrc": "6186:16:11", + "nodeType": "YulFunctionCall", + "src": "6186:16:11" + }, + "variableNames": + [ + { + "name": "prod0", + "nativeSrc": "6177:5:11", + "nodeType": "YulIdentifier", + "src": "6177:5:11" + } + ] + }, + { + "nativeSrc": "6317:39:11", + "nodeType": "YulAssignment", + "src": "6317:39:11", + "value": + { + "arguments": + [ + { + "arguments": + [ + { + "arguments": + [ + { + "kind": "number", + "nativeSrc": "6337:1:11", + "nodeType": "YulLiteral", + "src": "6337:1:11", + "type": "", + "value": "0" + }, + { + "name": "twos", + "nativeSrc": "6340:4:11", + "nodeType": "YulIdentifier", + "src": "6340:4:11" + } + ], + "functionName": + { + "name": "sub", + "nativeSrc": "6333:3:11", + "nodeType": "YulIdentifier", + "src": "6333:3:11" + }, + "nativeSrc": "6333:12:11", + "nodeType": "YulFunctionCall", + "src": "6333:12:11" + }, + { + "name": "twos", + "nativeSrc": "6347:4:11", + "nodeType": "YulIdentifier", + "src": "6347:4:11" + } + ], + "functionName": + { + "name": "div", + "nativeSrc": "6329:3:11", + "nodeType": "YulIdentifier", + "src": "6329:3:11" + }, + "nativeSrc": "6329:23:11", + "nodeType": "YulFunctionCall", + "src": "6329:23:11" + }, + { + "kind": "number", + "nativeSrc": "6354:1:11", + "nodeType": "YulLiteral", + "src": "6354:1:11", + "type": "", + "value": "1" + } + ], + "functionName": + { + "name": "add", + "nativeSrc": "6325:3:11", + "nodeType": "YulIdentifier", + "src": "6325:3:11" + }, + "nativeSrc": "6325:31:11", + "nodeType": "YulFunctionCall", + "src": "6325:31:11" + }, + "variableNames": + [ + { + "name": "twos", + "nativeSrc": "6317:4:11", + "nodeType": "YulIdentifier", + "src": "6317:4:11" + } + ] + } + ] + }, + "evmVersion": "shanghai", + "externalReferences": + [ + { + "declaration": 2658, + "isOffset": false, + "isSlot": false, + "src": "6073:11:11", + "valueSize": 1 + }, + { + "declaration": 2658, + "isOffset": false, + "isSlot": false, + "src": "6092:11:11", + "valueSize": 1 + }, + { + "declaration": 2664, + "isOffset": false, + "isSlot": false, + "src": "6177:5:11", + "valueSize": 1 + }, + { + "declaration": 2664, + "isOffset": false, + "isSlot": false, + "src": "6190:5:11", + "valueSize": 1 + }, + { + "declaration": 2695, + "isOffset": false, + "isSlot": false, + "src": "6105:4:11", + "valueSize": 1 + }, + { + "declaration": 2695, + "isOffset": false, + "isSlot": false, + "src": "6197:4:11", + "valueSize": 1 + }, + { + "declaration": 2695, + "isOffset": false, + "isSlot": false, + "src": "6317:4:11", + "valueSize": 1 + }, + { + "declaration": 2695, + "isOffset": false, + "isSlot": false, + "src": "6340:4:11", + "valueSize": 1 + }, + { + "declaration": 2695, + "isOffset": false, + "isSlot": false, + "src": "6347:4:11", + "valueSize": 1 + } + ], + "id": 2703, + "nodeType": "InlineAssembly", + "src": "5999:371:11" + }, + { + "expression": + { + "id": 2708, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2704, + "name": "prod0", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2664, + "src": "6436:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "|=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2707, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2705, + "name": "prod1", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2670, + "src": "6445:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2706, + "name": "twos", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2695, + "src": "6453:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6445:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6436:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2709, + "nodeType": "ExpressionStatement", + "src": "6436:21:11" + }, + { + "assignments": + [ + 2711 + ], + "declarations": + [ + { + "constant": false, + "id": 2711, + "mutability": "mutable", + "name": "inverse", + "nameLocation": "6783:7:11", + "nodeType": "VariableDeclaration", + "scope": 2775, + "src": "6775:15:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2710, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6775:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2718, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2717, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2714, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "33", + "id": 2712, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6794:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2713, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "6798:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6794:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2715, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "6793:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "^", + "rightExpression": + { + "hexValue": "32", + "id": 2716, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6813:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "6793:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "6775:39:11" + }, + { + "expression": + { + "id": 2725, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2719, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7031:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "32", + "id": 2720, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7042:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2723, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2721, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "7046:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2722, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7060:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7046:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7042:25:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7031:36:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2726, + "nodeType": "ExpressionStatement", + "src": "7031:36:11" + }, + { + "expression": + { + "id": 2733, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2727, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7100:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2732, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "32", + "id": 2728, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7111:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2731, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2729, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "7115:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2730, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7129:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7115:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7111:25:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7100:36:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2734, + "nodeType": "ExpressionStatement", + "src": "7100:36:11" + }, + { + "expression": + { + "id": 2741, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2735, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7170:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2740, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "32", + "id": 2736, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7181:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2739, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2737, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "7185:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2738, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7199:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7185:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7181:25:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7170:36:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2742, + "nodeType": "ExpressionStatement", + "src": "7170:36:11" + }, + { + "expression": + { + "id": 2749, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2743, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7240:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2748, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "32", + "id": 2744, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7251:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2747, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2745, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "7255:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2746, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7269:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7255:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7251:25:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7240:36:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2750, + "nodeType": "ExpressionStatement", + "src": "7240:36:11" + }, + { + "expression": + { + "id": 2757, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2751, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7310:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2756, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "32", + "id": 2752, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7321:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2755, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2753, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "7325:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2754, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7339:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7325:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7321:25:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7310:36:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2758, + "nodeType": "ExpressionStatement", + "src": "7310:36:11" + }, + { + "expression": + { + "id": 2765, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2759, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7381:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2764, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "32", + "id": 2760, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7392:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2763, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2761, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2658, + "src": "7396:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2762, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7410:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7396:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7392:25:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7381:36:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2766, + "nodeType": "ExpressionStatement", + "src": "7381:36:11" + }, + { + "expression": + { + "id": 2771, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2767, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2661, + "src": "7851:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2770, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2768, + "name": "prod0", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2664, + "src": "7860:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2769, + "name": "inverse", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2711, + "src": "7868:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7860:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7851:24:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2772, + "nodeType": "ExpressionStatement", + "src": "7851:24:11" + }, + { + "expression": + { + "id": 2773, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2661, + "src": "7896:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2662, + "id": 2774, + "nodeType": "Return", + "src": "7889:13:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2652, + "nodeType": "StructuredDocumentation", + "src": "3485:313:11", + "text": " @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n denominator == 0.\n @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n Uniswap Labs also under MIT license." + }, + "id": 2777, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "mulDiv", + "nameLocation": "3812:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2659, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2654, + "mutability": "mutable", + "name": "x", + "nameLocation": "3827:1:11", + "nodeType": "VariableDeclaration", + "scope": 2777, + "src": "3819:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2653, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3819:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2656, + "mutability": "mutable", + "name": "y", + "nameLocation": "3838:1:11", + "nodeType": "VariableDeclaration", + "scope": 2777, + "src": "3830:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2655, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3830:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2658, + "mutability": "mutable", + "name": "denominator", + "nameLocation": "3849:11:11", + "nodeType": "VariableDeclaration", + "scope": 2777, + "src": "3841:19:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2657, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3841:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3818:43:11" + }, + "returnParameters": + { + "id": 2662, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2661, + "mutability": "mutable", + "name": "result", + "nameLocation": "3893:6:11", + "nodeType": "VariableDeclaration", + "scope": 2777, + "src": "3885:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2660, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3885:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3884:16:11" + }, + "scope": 3443, + "src": "3803:4116:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2819, + "nodeType": "Block", + "src": "8161:192:11", + "statements": + [ + { + "assignments": + [ + 2793 + ], + "declarations": + [ + { + "constant": false, + "id": 2793, + "mutability": "mutable", + "name": "result", + "nameLocation": "8179:6:11", + "nodeType": "VariableDeclaration", + "scope": 2819, + "src": "8171:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2792, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8171:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2799, + "initialValue": + { + "arguments": + [ + { + "id": 2795, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2780, + "src": "8195:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2796, + "name": "y", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2782, + "src": "8198:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2797, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2784, + "src": "8201:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2794, + "name": "mulDiv", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 2777, + 2820 + ], + "referencedDeclaration": 2777, + "src": "8188:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" + } + }, + "id": 2798, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8188:25:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "8171:42:11" + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2810, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 2801, + "name": "rounding", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2787, + "src": "8244:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + ], + "id": 2800, + "name": "unsignedRoundsUp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3442, + "src": "8227:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_enum$_Rounding_$2400_$returns$_t_bool_$", + "typeString": "function (enum Math.Rounding) pure returns (bool)" + } + }, + "id": 2802, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8227:26:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2809, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 2804, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2780, + "src": "8264:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2805, + "name": "y", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2782, + "src": "8267:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2806, + "name": "denominator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2784, + "src": "8270:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2803, + "name": "mulmod", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -16, + "src": "8257:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" + } + }, + "id": 2807, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8257:25:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 2808, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8285:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "8257:29:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "8227:59:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2816, + "nodeType": "IfStatement", + "src": "8223:101:11", + "trueBody": + { + "id": 2815, + "nodeType": "Block", + "src": "8288:36:11", + "statements": + [ + { + "expression": + { + "id": 2813, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2811, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2793, + "src": "8302:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "31", + "id": 2812, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8312:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "8302:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2814, + "nodeType": "ExpressionStatement", + "src": "8302:11:11" + } + ] + } + }, + { + "expression": + { + "id": 2817, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2793, + "src": "8340:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2791, + "id": 2818, + "nodeType": "Return", + "src": "8333:13:11" + } + ] + }, + "documentation": + { + "id": 2778, + "nodeType": "StructuredDocumentation", + "src": "7925:121:11", + "text": " @notice Calculates x * y / denominator with full precision, following the selected rounding direction." + }, + "id": 2820, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "mulDiv", + "nameLocation": "8060:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2788, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2780, + "mutability": "mutable", + "name": "x", + "nameLocation": "8075:1:11", + "nodeType": "VariableDeclaration", + "scope": 2820, + "src": "8067:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2779, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8067:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2782, + "mutability": "mutable", + "name": "y", + "nameLocation": "8086:1:11", + "nodeType": "VariableDeclaration", + "scope": 2820, + "src": "8078:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2781, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8078:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2784, + "mutability": "mutable", + "name": "denominator", + "nameLocation": "8097:11:11", + "nodeType": "VariableDeclaration", + "scope": 2820, + "src": "8089:19:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2783, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8089:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2787, + "mutability": "mutable", + "name": "rounding", + "nameLocation": "8119:8:11", + "nodeType": "VariableDeclaration", + "scope": 2820, + "src": "8110:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + }, + "typeName": + { + "id": 2786, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2785, + "name": "Rounding", + "nameLocations": + [ + "8110:8:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2400, + "src": "8110:8:11" + }, + "referencedDeclaration": 2400, + "src": "8110:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + }, + "visibility": "internal" + } + ], + "src": "8066:62:11" + }, + "returnParameters": + { + "id": 2791, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2790, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2820, + "src": "8152:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2789, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8152:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "8151:9:11" + }, + "scope": 3443, + "src": "8051:302:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2931, + "nodeType": "Block", + "src": "8644:1585:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2830, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2828, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "8658:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "30", + "id": 2829, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8663:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "8658:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2834, + "nodeType": "IfStatement", + "src": "8654:45:11", + "trueBody": + { + "id": 2833, + "nodeType": "Block", + "src": "8666:33:11", + "statements": + [ + { + "expression": + { + "hexValue": "30", + "id": 2831, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8687:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "functionReturnParameters": 2827, + "id": 2832, + "nodeType": "Return", + "src": "8680:8:11" + } + ] + } + }, + { + "assignments": + [ + 2836 + ], + "declarations": + [ + { + "constant": false, + "id": 2836, + "mutability": "mutable", + "name": "result", + "nameLocation": "9386:6:11", + "nodeType": "VariableDeclaration", + "scope": 2931, + "src": "9378:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2835, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9378:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2845, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2844, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "31", + "id": 2837, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9395:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "nodeType": "BinaryOperation", + "operator": "<<", + "rightExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2842, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 2839, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "9406:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2838, + "name": "log2", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 3099, + 3134 + ], + "referencedDeclaration": 3099, + "src": "9401:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) pure returns (uint256)" + } + }, + "id": 2840, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9401:7:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2841, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9412:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9401:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2843, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "9400:14:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9395:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "9378:36:11" + }, + { + "id": 2930, + "nodeType": "UncheckedBlock", + "src": "9815:408:11", + "statements": + [ + { + "expression": + { + "id": 2855, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2846, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9839:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2854, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2851, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2847, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9849:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2850, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2848, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "9858:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2849, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9862:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9858:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9849:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2852, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "9848:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2853, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9873:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9848:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9839:35:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2856, + "nodeType": "ExpressionStatement", + "src": "9839:35:11" + }, + { + "expression": + { + "id": 2866, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2857, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9888:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2865, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2858, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9898:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2861, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2859, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "9907:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2860, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9911:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9907:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9898:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2863, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "9897:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2864, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9922:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9897:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9888:35:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2867, + "nodeType": "ExpressionStatement", + "src": "9888:35:11" + }, + { + "expression": + { + "id": 2877, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2868, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9937:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2876, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2873, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2869, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9947:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2872, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2870, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "9956:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2871, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9960:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9956:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9947:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2874, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "9946:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2875, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9971:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9946:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9937:35:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2878, + "nodeType": "ExpressionStatement", + "src": "9937:35:11" + }, + { + "expression": + { + "id": 2888, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2879, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9986:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2887, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2884, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2880, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "9996:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2883, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2881, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "10005:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2882, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10009:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10005:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9996:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2885, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "9995:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2886, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10020:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9995:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9986:35:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2889, + "nodeType": "ExpressionStatement", + "src": "9986:35:11" + }, + { + "expression": + { + "id": 2899, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2890, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10035:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2898, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2895, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2891, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10045:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2894, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2892, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "10054:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2893, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10058:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10054:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10045:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2896, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10044:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2897, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10069:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "10044:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10035:35:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2900, + "nodeType": "ExpressionStatement", + "src": "10035:35:11" + }, + { + "expression": + { + "id": 2910, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2901, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10084:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2909, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2906, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2902, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10094:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2905, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2903, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "10103:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2904, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10107:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10103:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10094:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2907, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10093:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2908, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10118:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "10093:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10084:35:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2911, + "nodeType": "ExpressionStatement", + "src": "10084:35:11" + }, + { + "expression": + { + "id": 2921, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2912, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10133:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2920, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2917, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2913, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10143:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2916, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2914, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "10152:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2915, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10156:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10152:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10143:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2918, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10142:21:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 2919, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10167:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "10142:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10133:35:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2922, + "nodeType": "ExpressionStatement", + "src": "10133:35:11" + }, + { + "expression": + { + "arguments": + [ + { + "id": 2924, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10193:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2927, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2925, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2823, + "src": "10201:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": + { + "id": 2926, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2836, + "src": "10205:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10201:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2923, + "name": "min", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2594, + "src": "10189:3:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 2928, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "10189:23:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2827, + "id": 2929, + "nodeType": "Return", + "src": "10182:30:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2821, + "nodeType": "StructuredDocumentation", + "src": "8359:223:11", + "text": " @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n towards zero.\n Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11)." + }, + "id": 2932, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "sqrt", + "nameLocation": "8596:4:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2824, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2823, + "mutability": "mutable", + "name": "a", + "nameLocation": "8609:1:11", + "nodeType": "VariableDeclaration", + "scope": 2932, + "src": "8601:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2822, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8601:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "8600:11:11" + }, + "returnParameters": + { + "id": 2827, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2826, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2932, + "src": "8635:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2825, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8635:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "8634:9:11" + }, + "scope": 3443, + "src": "8587:1642:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 2966, + "nodeType": "Block", + "src": "10405:164:11", + "statements": + [ + { + "id": 2965, + "nodeType": "UncheckedBlock", + "src": "10415:148:11", + "statements": + [ + { + "assignments": + [ + 2944 + ], + "declarations": + [ + { + "constant": false, + "id": 2944, + "mutability": "mutable", + "name": "result", + "nameLocation": "10447:6:11", + "nodeType": "VariableDeclaration", + "scope": 2965, + "src": "10439:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2943, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10439:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2948, + "initialValue": + { + "arguments": + [ + { + "id": 2946, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2935, + "src": "10461:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2945, + "name": "sqrt", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 2932, + 2967 + ], + "referencedDeclaration": 2932, + "src": "10456:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) pure returns (uint256)" + } + }, + "id": 2947, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "10456:7:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "10439:24:11" + }, + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2963, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2949, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2944, + "src": "10484:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "components": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2958, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 2951, + "name": "rounding", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2938, + "src": "10511:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + ], + "id": 2950, + "name": "unsignedRoundsUp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3442, + "src": "10494:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_enum$_Rounding_$2400_$returns$_t_bool_$", + "typeString": "function (enum Math.Rounding) pure returns (bool)" + } + }, + "id": 2952, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "10494:26:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2957, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2955, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2953, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2944, + "src": "10524:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": + { + "id": 2954, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2944, + "src": "10533:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10524:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 2956, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2935, + "src": "10542:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10524:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "10494:49:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": + { + "hexValue": "30", + "id": 2960, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10550:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "id": 2961, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "10494:57:11", + "trueExpression": + { + "hexValue": "31", + "id": 2959, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10546:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 2962, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10493:59:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "10484:68:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2942, + "id": 2964, + "nodeType": "Return", + "src": "10477:75:11" + } + ] + } + ] + }, + "documentation": + { + "id": 2933, + "nodeType": "StructuredDocumentation", + "src": "10235:89:11", + "text": " @notice Calculates sqrt(a), following the selected rounding direction." + }, + "id": 2967, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "sqrt", + "nameLocation": "10338:4:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2939, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2935, + "mutability": "mutable", + "name": "a", + "nameLocation": "10351:1:11", + "nodeType": "VariableDeclaration", + "scope": 2967, + "src": "10343:9:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2934, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10343:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2938, + "mutability": "mutable", + "name": "rounding", + "nameLocation": "10363:8:11", + "nodeType": "VariableDeclaration", + "scope": 2967, + "src": "10354:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + }, + "typeName": + { + "id": 2937, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 2936, + "name": "Rounding", + "nameLocations": + [ + "10354:8:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2400, + "src": "10354:8:11" + }, + "referencedDeclaration": 2400, + "src": "10354:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + }, + "visibility": "internal" + } + ], + "src": "10342:30:11" + }, + "returnParameters": + { + "id": 2942, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2941, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2967, + "src": "10396:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2940, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10396:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "10395:9:11" + }, + "scope": 3443, + "src": "10329:240:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3098, + "nodeType": "Block", + "src": "10760:922:11", + "statements": + [ + { + "assignments": + [ + 2976 + ], + "declarations": + [ + { + "constant": false, + "id": 2976, + "mutability": "mutable", + "name": "result", + "nameLocation": "10778:6:11", + "nodeType": "VariableDeclaration", + "scope": 3098, + "src": "10770:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2975, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10770:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2978, + "initialValue": + { + "hexValue": "30", + "id": 2977, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10787:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "10770:18:11" + }, + { + "id": 3095, + "nodeType": "UncheckedBlock", + "src": "10798:855:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2983, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2981, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2979, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "10826:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "313238", + "id": 2980, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10835:3:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_128_by_1", + "typeString": "int_const 128" + }, + "value": "128" + }, + "src": "10826:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 2982, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10841:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10826:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2993, + "nodeType": "IfStatement", + "src": "10822:99:11", + "trueBody": + { + "id": 2992, + "nodeType": "Block", + "src": "10844:77:11", + "statements": + [ + { + "expression": + { + "id": 2986, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2984, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "10862:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "313238", + "id": 2985, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10872:3:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_128_by_1", + "typeString": "int_const 128" + }, + "value": "128" + }, + "src": "10862:13:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2987, + "nodeType": "ExpressionStatement", + "src": "10862:13:11" + }, + { + "expression": + { + "id": 2990, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2988, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "10893:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "313238", + "id": 2989, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10903:3:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_128_by_1", + "typeString": "int_const 128" + }, + "value": "128" + }, + "src": "10893:13:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2991, + "nodeType": "ExpressionStatement", + "src": "10893:13:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2996, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 2994, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "10938:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "3634", + "id": 2995, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10947:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "10938:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 2997, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10952:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10938:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3008, + "nodeType": "IfStatement", + "src": "10934:96:11", + "trueBody": + { + "id": 3007, + "nodeType": "Block", + "src": "10955:75:11", + "statements": + [ + { + "expression": + { + "id": 3001, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 2999, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "10973:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "3634", + "id": 3000, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10983:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "10973:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3002, + "nodeType": "ExpressionStatement", + "src": "10973:12:11" + }, + { + "expression": + { + "id": 3005, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3003, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11003:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "3634", + "id": 3004, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11013:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "11003:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3006, + "nodeType": "ExpressionStatement", + "src": "11003:12:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3013, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3011, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3009, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11047:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "3332", + "id": 3010, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11056:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "11047:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3012, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11061:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11047:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3023, + "nodeType": "IfStatement", + "src": "11043:96:11", + "trueBody": + { + "id": 3022, + "nodeType": "Block", + "src": "11064:75:11", + "statements": + [ + { + "expression": + { + "id": 3016, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3014, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11082:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "3332", + "id": 3015, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11092:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "11082:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3017, + "nodeType": "ExpressionStatement", + "src": "11082:12:11" + }, + { + "expression": + { + "id": 3020, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3018, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11112:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "3332", + "id": 3019, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11122:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "11112:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3021, + "nodeType": "ExpressionStatement", + "src": "11112:12:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3028, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3026, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3024, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11156:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "3136", + "id": 3025, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11165:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "11156:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3027, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11170:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11156:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3038, + "nodeType": "IfStatement", + "src": "11152:96:11", + "trueBody": + { + "id": 3037, + "nodeType": "Block", + "src": "11173:75:11", + "statements": + [ + { + "expression": + { + "id": 3031, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3029, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11191:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "3136", + "id": 3030, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11201:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "11191:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3032, + "nodeType": "ExpressionStatement", + "src": "11191:12:11" + }, + { + "expression": + { + "id": 3035, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3033, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11221:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "3136", + "id": 3034, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11231:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "11221:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3036, + "nodeType": "ExpressionStatement", + "src": "11221:12:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3043, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3041, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3039, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11265:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "38", + "id": 3040, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11274:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "11265:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3042, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11278:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11265:14:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3053, + "nodeType": "IfStatement", + "src": "11261:93:11", + "trueBody": + { + "id": 3052, + "nodeType": "Block", + "src": "11281:73:11", + "statements": + [ + { + "expression": + { + "id": 3046, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3044, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11299:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "38", + "id": 3045, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11309:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "11299:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3047, + "nodeType": "ExpressionStatement", + "src": "11299:11:11" + }, + { + "expression": + { + "id": 3050, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3048, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11328:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "38", + "id": 3049, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11338:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "11328:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3051, + "nodeType": "ExpressionStatement", + "src": "11328:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3058, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3056, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3054, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11371:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "34", + "id": 3055, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11380:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "11371:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3057, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11384:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11371:14:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3068, + "nodeType": "IfStatement", + "src": "11367:93:11", + "trueBody": + { + "id": 3067, + "nodeType": "Block", + "src": "11387:73:11", + "statements": + [ + { + "expression": + { + "id": 3061, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3059, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11405:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "34", + "id": 3060, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11415:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "11405:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3062, + "nodeType": "ExpressionStatement", + "src": "11405:11:11" + }, + { + "expression": + { + "id": 3065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3063, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11434:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "34", + "id": 3064, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11444:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "11434:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3066, + "nodeType": "ExpressionStatement", + "src": "11434:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3073, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3071, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3069, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11477:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "32", + "id": 3070, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11486:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "11477:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3072, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11490:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11477:14:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3083, + "nodeType": "IfStatement", + "src": "11473:93:11", + "trueBody": + { + "id": 3082, + "nodeType": "Block", + "src": "11493:73:11", + "statements": + [ + { + "expression": + { + "id": 3076, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3074, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11511:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "32", + "id": 3075, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11521:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "11511:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3077, + "nodeType": "ExpressionStatement", + "src": "11511:11:11" + }, + { + "expression": + { + "id": 3080, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3078, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11540:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "32", + "id": 3079, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11550:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "11540:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3081, + "nodeType": "ExpressionStatement", + "src": "11540:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3088, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3086, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3084, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2970, + "src": "11583:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "31", + "id": 3085, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11592:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "11583:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3087, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11596:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11583:14:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3094, + "nodeType": "IfStatement", + "src": "11579:64:11", + "trueBody": + { + "id": 3093, + "nodeType": "Block", + "src": "11599:44:11", + "statements": + [ + { + "expression": + { + "id": 3091, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3089, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11617:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "31", + "id": 3090, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11627:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "11617:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3092, + "nodeType": "ExpressionStatement", + "src": "11617:11:11" + } + ] + } + } + ] + }, + { + "expression": + { + "id": 3096, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2976, + "src": "11669:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2974, + "id": 3097, + "nodeType": "Return", + "src": "11662:13:11" + } + ] + }, + "documentation": + { + "id": 2968, + "nodeType": "StructuredDocumentation", + "src": "10575:119:11", + "text": " @dev Return the log in base 2 of a positive value rounded towards zero.\n Returns 0 if given 0." + }, + "id": 3099, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "log2", + "nameLocation": "10708:4:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 2971, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2970, + "mutability": "mutable", + "name": "value", + "nameLocation": "10721:5:11", + "nodeType": "VariableDeclaration", + "scope": 3099, + "src": "10713:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2969, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10713:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "10712:15:11" + }, + "returnParameters": + { + "id": 2974, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2973, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3099, + "src": "10751:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2972, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10751:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "10750:9:11" + }, + "scope": 3443, + "src": "10699:983:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3133, + "nodeType": "Block", + "src": "11915:168:11", + "statements": + [ + { + "id": 3132, + "nodeType": "UncheckedBlock", + "src": "11925:152:11", + "statements": + [ + { + "assignments": + [ + 3111 + ], + "declarations": + [ + { + "constant": false, + "id": 3111, + "mutability": "mutable", + "name": "result", + "nameLocation": "11957:6:11", + "nodeType": "VariableDeclaration", + "scope": 3132, + "src": "11949:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3110, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11949:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 3115, + "initialValue": + { + "arguments": + [ + { + "id": 3113, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3102, + "src": "11971:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 3112, + "name": "log2", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 3099, + 3134 + ], + "referencedDeclaration": 3099, + "src": "11966:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) pure returns (uint256)" + } + }, + "id": 3114, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "11966:11:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11949:28:11" + }, + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3130, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3116, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3111, + "src": "11998:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "components": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 3125, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 3118, + "name": "rounding", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3105, + "src": "12025:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + ], + "id": 3117, + "name": "unsignedRoundsUp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3442, + "src": "12008:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_enum$_Rounding_$2400_$returns$_t_bool_$", + "typeString": "function (enum Math.Rounding) pure returns (bool)" + } + }, + "id": 3119, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12008:26:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3124, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3122, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "31", + "id": 3120, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12038:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "nodeType": "BinaryOperation", + "operator": "<<", + "rightExpression": + { + "id": 3121, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3111, + "src": "12043:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12038:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 3123, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3102, + "src": "12052:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12038:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "12008:49:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": + { + "hexValue": "30", + "id": 3127, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12064:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "id": 3128, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "12008:57:11", + "trueExpression": + { + "hexValue": "31", + "id": 3126, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12060:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 3129, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "12007:59:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "11998:68:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 3109, + "id": 3131, + "nodeType": "Return", + "src": "11991:75:11" + } + ] + } + ] + }, + "documentation": + { + "id": 3100, + "nodeType": "StructuredDocumentation", + "src": "11688:142:11", + "text": " @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n Returns 0 if given 0." + }, + "id": 3134, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "log2", + "nameLocation": "11844:4:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3106, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3102, + "mutability": "mutable", + "name": "value", + "nameLocation": "11857:5:11", + "nodeType": "VariableDeclaration", + "scope": 3134, + "src": "11849:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3101, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11849:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3105, + "mutability": "mutable", + "name": "rounding", + "nameLocation": "11873:8:11", + "nodeType": "VariableDeclaration", + "scope": 3134, + "src": "11864:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + }, + "typeName": + { + "id": 3104, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 3103, + "name": "Rounding", + "nameLocations": + [ + "11864:8:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2400, + "src": "11864:8:11" + }, + "referencedDeclaration": 2400, + "src": "11864:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + }, + "visibility": "internal" + } + ], + "src": "11848:34:11" + }, + "returnParameters": + { + "id": 3109, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3108, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3134, + "src": "11906:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3107, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11906:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "11905:9:11" + }, + "scope": 3443, + "src": "11835:248:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3262, + "nodeType": "Block", + "src": "12276:854:11", + "statements": + [ + { + "assignments": + [ + 3143 + ], + "declarations": + [ + { + "constant": false, + "id": 3143, + "mutability": "mutable", + "name": "result", + "nameLocation": "12294:6:11", + "nodeType": "VariableDeclaration", + "scope": 3262, + "src": "12286:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3142, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "12286:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 3145, + "initialValue": + { + "hexValue": "30", + "id": 3144, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12303:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "12286:18:11" + }, + { + "id": 3259, + "nodeType": "UncheckedBlock", + "src": "12314:787:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3150, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3146, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12342:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(57 digits omitted)...0000" + }, + "id": 3149, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3147, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12351:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "3634", + "id": 3148, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12357:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "12351:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(57 digits omitted)...0000" + } + }, + "src": "12342:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3162, + "nodeType": "IfStatement", + "src": "12338:103:11", + "trueBody": + { + "id": 3161, + "nodeType": "Block", + "src": "12361:80:11", + "statements": + [ + { + "expression": + { + "id": 3155, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3151, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12379:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "/=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(57 digits omitted)...0000" + }, + "id": 3154, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3152, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12388:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "3634", + "id": 3153, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12394:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "12388:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(57 digits omitted)...0000" + } + }, + "src": "12379:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3156, + "nodeType": "ExpressionStatement", + "src": "12379:17:11" + }, + { + "expression": + { + "id": 3159, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3157, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "12414:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "3634", + "id": 3158, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12424:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "12414:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3160, + "nodeType": "ExpressionStatement", + "src": "12414:12:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3167, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3163, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12458:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_rational_100000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(25 digits omitted)...0000" + }, + "id": 3166, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3164, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12467:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "3332", + "id": 3165, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12473:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "12467:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_100000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(25 digits omitted)...0000" + } + }, + "src": "12458:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3179, + "nodeType": "IfStatement", + "src": "12454:103:11", + "trueBody": + { + "id": 3178, + "nodeType": "Block", + "src": "12477:80:11", + "statements": + [ + { + "expression": + { + "id": 3172, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3168, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12495:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "/=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_rational_100000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(25 digits omitted)...0000" + }, + "id": 3171, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3169, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12504:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "3332", + "id": 3170, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12510:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "12504:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_100000000000000000000000000000000_by_1", + "typeString": "int_const 1000...(25 digits omitted)...0000" + } + }, + "src": "12495:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3173, + "nodeType": "ExpressionStatement", + "src": "12495:17:11" + }, + { + "expression": + { + "id": 3176, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3174, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "12530:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "3332", + "id": 3175, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12540:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "12530:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3177, + "nodeType": "ExpressionStatement", + "src": "12530:12:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3184, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3180, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12574:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_rational_10000000000000000_by_1", + "typeString": "int_const 10000000000000000" + }, + "id": 3183, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3181, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12583:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "3136", + "id": 3182, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12589:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "12583:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10000000000000000_by_1", + "typeString": "int_const 10000000000000000" + } + }, + "src": "12574:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3196, + "nodeType": "IfStatement", + "src": "12570:103:11", + "trueBody": + { + "id": 3195, + "nodeType": "Block", + "src": "12593:80:11", + "statements": + [ + { + "expression": + { + "id": 3189, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3185, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12611:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "/=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_rational_10000000000000000_by_1", + "typeString": "int_const 10000000000000000" + }, + "id": 3188, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3186, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12620:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "3136", + "id": 3187, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12626:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "12620:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10000000000000000_by_1", + "typeString": "int_const 10000000000000000" + } + }, + "src": "12611:17:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3190, + "nodeType": "ExpressionStatement", + "src": "12611:17:11" + }, + { + "expression": + { + "id": 3193, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3191, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "12646:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "3136", + "id": 3192, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12656:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "12646:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3194, + "nodeType": "ExpressionStatement", + "src": "12646:12:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3201, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3197, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12690:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_rational_100000000_by_1", + "typeString": "int_const 100000000" + }, + "id": 3200, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3198, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12699:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "38", + "id": 3199, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12705:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "12699:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_100000000_by_1", + "typeString": "int_const 100000000" + } + }, + "src": "12690:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3213, + "nodeType": "IfStatement", + "src": "12686:100:11", + "trueBody": + { + "id": 3212, + "nodeType": "Block", + "src": "12708:78:11", + "statements": + [ + { + "expression": + { + "id": 3206, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3202, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12726:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "/=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_rational_100000000_by_1", + "typeString": "int_const 100000000" + }, + "id": 3205, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3203, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12735:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "38", + "id": 3204, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12741:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "12735:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_100000000_by_1", + "typeString": "int_const 100000000" + } + }, + "src": "12726:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3207, + "nodeType": "ExpressionStatement", + "src": "12726:16:11" + }, + { + "expression": + { + "id": 3210, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3208, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "12760:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "38", + "id": 3209, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12770:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "12760:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3211, + "nodeType": "ExpressionStatement", + "src": "12760:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3218, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3214, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12803:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_rational_10000_by_1", + "typeString": "int_const 10000" + }, + "id": 3217, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3215, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12812:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "34", + "id": 3216, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12818:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "12812:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10000_by_1", + "typeString": "int_const 10000" + } + }, + "src": "12803:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3230, + "nodeType": "IfStatement", + "src": "12799:100:11", + "trueBody": + { + "id": 3229, + "nodeType": "Block", + "src": "12821:78:11", + "statements": + [ + { + "expression": + { + "id": 3223, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3219, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12839:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "/=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_rational_10000_by_1", + "typeString": "int_const 10000" + }, + "id": 3222, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3220, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12848:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "34", + "id": 3221, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12854:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "12848:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10000_by_1", + "typeString": "int_const 10000" + } + }, + "src": "12839:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3224, + "nodeType": "ExpressionStatement", + "src": "12839:16:11" + }, + { + "expression": + { + "id": 3227, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3225, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "12873:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "34", + "id": 3226, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12883:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "12873:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3228, + "nodeType": "ExpressionStatement", + "src": "12873:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3235, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3231, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12916:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_rational_100_by_1", + "typeString": "int_const 100" + }, + "id": 3234, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3232, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12925:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "32", + "id": 3233, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12931:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "12925:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_100_by_1", + "typeString": "int_const 100" + } + }, + "src": "12916:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3247, + "nodeType": "IfStatement", + "src": "12912:100:11", + "trueBody": + { + "id": 3246, + "nodeType": "Block", + "src": "12934:78:11", + "statements": + [ + { + "expression": + { + "id": 3240, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3236, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "12952:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "/=", + "rightHandSide": + { + "commonType": + { + "typeIdentifier": "t_rational_100_by_1", + "typeString": "int_const 100" + }, + "id": 3239, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3237, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12961:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "32", + "id": 3238, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12967:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "12961:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_100_by_1", + "typeString": "int_const 100" + } + }, + "src": "12952:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3241, + "nodeType": "ExpressionStatement", + "src": "12952:16:11" + }, + { + "expression": + { + "id": 3244, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3242, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "12986:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "32", + "id": 3243, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12996:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "12986:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3245, + "nodeType": "ExpressionStatement", + "src": "12986:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3252, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3248, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3137, + "src": "13029:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "id": 3251, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3249, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13038:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "hexValue": "31", + "id": 3250, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13044:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "13038:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + } + }, + "src": "13029:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3258, + "nodeType": "IfStatement", + "src": "13025:66:11", + "trueBody": + { + "id": 3257, + "nodeType": "Block", + "src": "13047:44:11", + "statements": + [ + { + "expression": + { + "id": 3255, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3253, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "13065:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "31", + "id": 3254, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13075:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "13065:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3256, + "nodeType": "ExpressionStatement", + "src": "13065:11:11" + } + ] + } + } + ] + }, + { + "expression": + { + "id": 3260, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3143, + "src": "13117:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 3141, + "id": 3261, + "nodeType": "Return", + "src": "13110:13:11" + } + ] + }, + "documentation": + { + "id": 3135, + "nodeType": "StructuredDocumentation", + "src": "12089:120:11", + "text": " @dev Return the log in base 10 of a positive value rounded towards zero.\n Returns 0 if given 0." + }, + "id": 3263, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "log10", + "nameLocation": "12223:5:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3138, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3137, + "mutability": "mutable", + "name": "value", + "nameLocation": "12237:5:11", + "nodeType": "VariableDeclaration", + "scope": 3263, + "src": "12229:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3136, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "12229:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "12228:15:11" + }, + "returnParameters": + { + "id": 3141, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3140, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3263, + "src": "12267:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3139, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "12267:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "12266:9:11" + }, + "scope": 3443, + "src": "12214:916:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3297, + "nodeType": "Block", + "src": "13365:170:11", + "statements": + [ + { + "id": 3296, + "nodeType": "UncheckedBlock", + "src": "13375:154:11", + "statements": + [ + { + "assignments": + [ + 3275 + ], + "declarations": + [ + { + "constant": false, + "id": 3275, + "mutability": "mutable", + "name": "result", + "nameLocation": "13407:6:11", + "nodeType": "VariableDeclaration", + "scope": 3296, + "src": "13399:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3274, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13399:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 3279, + "initialValue": + { + "arguments": + [ + { + "id": 3277, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3266, + "src": "13422:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 3276, + "name": "log10", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 3263, + 3298 + ], + "referencedDeclaration": 3263, + "src": "13416:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) pure returns (uint256)" + } + }, + "id": 3278, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13416:12:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "13399:29:11" + }, + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3294, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3280, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3275, + "src": "13449:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "components": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 3289, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 3282, + "name": "rounding", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3269, + "src": "13476:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + ], + "id": 3281, + "name": "unsignedRoundsUp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3442, + "src": "13459:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_enum$_Rounding_$2400_$returns$_t_bool_$", + "typeString": "function (enum Math.Rounding) pure returns (bool)" + } + }, + "id": 3283, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13459:26:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3288, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3286, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "3130", + "id": 3284, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13489:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": + { + "id": 3285, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3275, + "src": "13495:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13489:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 3287, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3266, + "src": "13504:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13489:20:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13459:50:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": + { + "hexValue": "30", + "id": 3291, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13516:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "id": 3292, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "13459:58:11", + "trueExpression": + { + "hexValue": "31", + "id": 3290, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13512:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 3293, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13458:60:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "13449:69:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 3273, + "id": 3295, + "nodeType": "Return", + "src": "13442:76:11" + } + ] + } + ] + }, + "documentation": + { + "id": 3264, + "nodeType": "StructuredDocumentation", + "src": "13136:143:11", + "text": " @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n Returns 0 if given 0." + }, + "id": 3298, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "log10", + "nameLocation": "13293:5:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3270, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3266, + "mutability": "mutable", + "name": "value", + "nameLocation": "13307:5:11", + "nodeType": "VariableDeclaration", + "scope": 3298, + "src": "13299:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3265, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13299:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3269, + "mutability": "mutable", + "name": "rounding", + "nameLocation": "13323:8:11", + "nodeType": "VariableDeclaration", + "scope": 3298, + "src": "13314:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + }, + "typeName": + { + "id": 3268, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 3267, + "name": "Rounding", + "nameLocations": + [ + "13314:8:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2400, + "src": "13314:8:11" + }, + "referencedDeclaration": 2400, + "src": "13314:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + }, + "visibility": "internal" + } + ], + "src": "13298:34:11" + }, + "returnParameters": + { + "id": 3273, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3272, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3298, + "src": "13356:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3271, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13356:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "13355:9:11" + }, + "scope": 3443, + "src": "13284:251:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3384, + "nodeType": "Block", + "src": "13855:600:11", + "statements": + [ + { + "assignments": + [ + 3307 + ], + "declarations": + [ + { + "constant": false, + "id": 3307, + "mutability": "mutable", + "name": "result", + "nameLocation": "13873:6:11", + "nodeType": "VariableDeclaration", + "scope": 3384, + "src": "13865:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3306, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13865:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 3309, + "initialValue": + { + "hexValue": "30", + "id": 3308, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13882:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "13865:18:11" + }, + { + "id": 3381, + "nodeType": "UncheckedBlock", + "src": "13893:533:11", + "statements": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3314, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3312, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3310, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "13921:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "313238", + "id": 3311, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13930:3:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_128_by_1", + "typeString": "int_const 128" + }, + "value": "128" + }, + "src": "13921:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3313, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13936:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13921:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3324, + "nodeType": "IfStatement", + "src": "13917:98:11", + "trueBody": + { + "id": 3323, + "nodeType": "Block", + "src": "13939:76:11", + "statements": + [ + { + "expression": + { + "id": 3317, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3315, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "13957:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "313238", + "id": 3316, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13967:3:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_128_by_1", + "typeString": "int_const 128" + }, + "value": "128" + }, + "src": "13957:13:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3318, + "nodeType": "ExpressionStatement", + "src": "13957:13:11" + }, + { + "expression": + { + "id": 3321, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3319, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3307, + "src": "13988:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "3136", + "id": 3320, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13998:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "13988:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3322, + "nodeType": "ExpressionStatement", + "src": "13988:12:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3329, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3327, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3325, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "14032:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "3634", + "id": 3326, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14041:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "14032:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3328, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14046:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "14032:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3339, + "nodeType": "IfStatement", + "src": "14028:95:11", + "trueBody": + { + "id": 3338, + "nodeType": "Block", + "src": "14049:74:11", + "statements": + [ + { + "expression": + { + "id": 3332, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3330, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "14067:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "3634", + "id": 3331, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14077:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "14067:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3333, + "nodeType": "ExpressionStatement", + "src": "14067:12:11" + }, + { + "expression": + { + "id": 3336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3334, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3307, + "src": "14097:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "38", + "id": 3335, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14107:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "14097:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3337, + "nodeType": "ExpressionStatement", + "src": "14097:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3344, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3342, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3340, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "14140:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "3332", + "id": 3341, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14149:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "14140:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3343, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14154:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "14140:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3354, + "nodeType": "IfStatement", + "src": "14136:95:11", + "trueBody": + { + "id": 3353, + "nodeType": "Block", + "src": "14157:74:11", + "statements": + [ + { + "expression": + { + "id": 3347, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3345, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "14175:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "3332", + "id": 3346, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14185:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "14175:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3348, + "nodeType": "ExpressionStatement", + "src": "14175:12:11" + }, + { + "expression": + { + "id": 3351, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3349, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3307, + "src": "14205:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "34", + "id": 3350, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14215:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "14205:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3352, + "nodeType": "ExpressionStatement", + "src": "14205:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3359, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3357, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3355, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "14248:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "3136", + "id": 3356, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14257:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "14248:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3358, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14262:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "14248:15:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3369, + "nodeType": "IfStatement", + "src": "14244:95:11", + "trueBody": + { + "id": 3368, + "nodeType": "Block", + "src": "14265:74:11", + "statements": + [ + { + "expression": + { + "id": 3362, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3360, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "14283:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": ">>=", + "rightHandSide": + { + "hexValue": "3136", + "id": 3361, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14293:2:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_16_by_1", + "typeString": "int_const 16" + }, + "value": "16" + }, + "src": "14283:12:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3363, + "nodeType": "ExpressionStatement", + "src": "14283:12:11" + }, + { + "expression": + { + "id": 3366, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3364, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3307, + "src": "14313:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "32", + "id": 3365, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14323:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "14313:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3367, + "nodeType": "ExpressionStatement", + "src": "14313:11:11" + } + ] + } + }, + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3374, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3372, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3370, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3301, + "src": "14356:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": + { + "hexValue": "38", + "id": 3371, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14365:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "src": "14356:10:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": + { + "hexValue": "30", + "id": 3373, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14369:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "14356:14:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 3380, + "nodeType": "IfStatement", + "src": "14352:64:11", + "trueBody": + { + "id": 3379, + "nodeType": "Block", + "src": "14372:44:11", + "statements": + [ + { + "expression": + { + "id": 3377, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 3375, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3307, + "src": "14390:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": + { + "hexValue": "31", + "id": 3376, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14400:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "14390:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 3378, + "nodeType": "ExpressionStatement", + "src": "14390:11:11" + } + ] + } + } + ] + }, + { + "expression": + { + "id": 3382, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3307, + "src": "14442:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 3305, + "id": 3383, + "nodeType": "Return", + "src": "14435:13:11" + } + ] + }, + "documentation": + { + "id": 3299, + "nodeType": "StructuredDocumentation", + "src": "13541:246:11", + "text": " @dev Return the log in base 256 of a positive value rounded towards zero.\n Returns 0 if given 0.\n Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string." + }, + "id": 3385, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "log256", + "nameLocation": "13801:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3302, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3301, + "mutability": "mutable", + "name": "value", + "nameLocation": "13816:5:11", + "nodeType": "VariableDeclaration", + "scope": 3385, + "src": "13808:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3300, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13808:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "13807:15:11" + }, + "returnParameters": + { + "id": 3305, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3304, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3385, + "src": "13846:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3303, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13846:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "13845:9:11" + }, + "scope": 3443, + "src": "13792:663:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3422, + "nodeType": "Block", + "src": "14692:177:11", + "statements": + [ + { + "id": 3421, + "nodeType": "UncheckedBlock", + "src": "14702:161:11", + "statements": + [ + { + "assignments": + [ + 3397 + ], + "declarations": + [ + { + "constant": false, + "id": 3397, + "mutability": "mutable", + "name": "result", + "nameLocation": "14734:6:11", + "nodeType": "VariableDeclaration", + "scope": 3421, + "src": "14726:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3396, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14726:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 3401, + "initialValue": + { + "arguments": + [ + { + "id": 3399, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3388, + "src": "14750:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 3398, + "name": "log256", + "nodeType": "Identifier", + "overloadedDeclarations": + [ + 3385, + 3423 + ], + "referencedDeclaration": 3385, + "src": "14743:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) pure returns (uint256)" + } + }, + "id": 3400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "14743:13:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "14726:30:11" + }, + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3419, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3402, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3397, + "src": "14777:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "components": + [ + { + "condition": + { + "commonType": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 3414, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 3404, + "name": "rounding", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3391, + "src": "14804:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + ], + "id": 3403, + "name": "unsignedRoundsUp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3442, + "src": "14787:16:11", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$_t_enum$_Rounding_$2400_$returns$_t_bool_$", + "typeString": "function (enum Math.Rounding) pure returns (bool)" + } + }, + "id": 3405, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "14787:26:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3413, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3411, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "31", + "id": 3406, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14817:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "nodeType": "BinaryOperation", + "operator": "<<", + "rightExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 3409, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 3407, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3397, + "src": "14823:6:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<<", + "rightExpression": + { + "hexValue": "33", + "id": 3408, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14833:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "src": "14823:11:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 3410, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14822:13:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14817:18:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "id": 3412, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3388, + "src": "14838:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14817:26:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "14787:56:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": + { + "hexValue": "30", + "id": 3416, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14850:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "id": 3417, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "14787:64:11", + "trueExpression": + { + "hexValue": "31", + "id": 3415, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14846:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 3418, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14786:66:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "14777:75:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 3395, + "id": 3420, + "nodeType": "Return", + "src": "14770:82:11" + } + ] + } + ] + }, + "documentation": + { + "id": 3386, + "nodeType": "StructuredDocumentation", + "src": "14461:144:11", + "text": " @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n Returns 0 if given 0." + }, + "id": 3423, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "log256", + "nameLocation": "14619:6:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3392, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3388, + "mutability": "mutable", + "name": "value", + "nameLocation": "14634:5:11", + "nodeType": "VariableDeclaration", + "scope": 3423, + "src": "14626:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3387, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14626:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 3391, + "mutability": "mutable", + "name": "rounding", + "nameLocation": "14650:8:11", + "nodeType": "VariableDeclaration", + "scope": 3423, + "src": "14641:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + }, + "typeName": + { + "id": 3390, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 3389, + "name": "Rounding", + "nameLocations": + [ + "14641:8:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2400, + "src": "14641:8:11" + }, + "referencedDeclaration": 2400, + "src": "14641:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + }, + "visibility": "internal" + } + ], + "src": "14625:34:11" + }, + "returnParameters": + { + "id": 3395, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3394, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3423, + "src": "14683:7:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3393, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14683:7:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "14682:9:11" + }, + "scope": 3443, + "src": "14610:259:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 3441, + "nodeType": "Block", + "src": "15067:48:11", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 3439, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "commonType": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 3437, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "id": 3434, + "name": "rounding", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3427, + "src": "15090:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + ], + "id": 3433, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "15084:5:11", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_uint8_$", + "typeString": "type(uint8)" + }, + "typeName": + { + "id": 3432, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "15084:5:11", + "typeDescriptions": {} + } + }, + "id": 3435, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "15084:15:11", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "%", + "rightExpression": + { + "hexValue": "32", + "id": 3436, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15102:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "15084:19:11", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": + { + "hexValue": "31", + "id": 3438, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15107:1:11", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "15084:24:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 3431, + "id": 3440, + "nodeType": "Return", + "src": "15077:31:11" + } + ] + }, + "documentation": + { + "id": 3424, + "nodeType": "StructuredDocumentation", + "src": "14875:113:11", + "text": " @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers." + }, + "id": 3442, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "unsignedRoundsUp", + "nameLocation": "15002:16:11", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3428, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3427, + "mutability": "mutable", + "name": "rounding", + "nameLocation": "15028:8:11", + "nodeType": "VariableDeclaration", + "scope": 3442, + "src": "15019:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + }, + "typeName": + { + "id": 3426, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 3425, + "name": "Rounding", + "nameLocations": + [ + "15019:8:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2400, + "src": "15019:8:11" + }, + "referencedDeclaration": 2400, + "src": "15019:8:11", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_Rounding_$2400", + "typeString": "enum Math.Rounding" + } + }, + "visibility": "internal" + } + ], + "src": "15018:19:11" + }, + "returnParameters": + { + "id": 3431, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3430, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 3442, + "src": "15061:4:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 3429, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "15061:4:11", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "15060:6:11" + }, + "scope": 3443, + "src": "14993:122:11", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 3444, + "src": "203:14914:11", + "usedErrors": + [ + 2395 + ], + "usedEvents": [] + } + ], + "src": "103:15015:11" + }, + "id": 11 + } + }, + "version": "0.8.25+commit.b61c2a91.Darwin.appleclang" +} diff --git a/relayer/README.md b/relayer/README.md index cbb63d2d8..893ab0b73 100644 --- a/relayer/README.md +++ b/relayer/README.md @@ -507,7 +507,7 @@ _Note:_ Given these semantics for computing the starting block height, it's poss Unit tests can be ran locally by running the command in the root of the project: ```bash -./scripts/test.sh +./scripts/unit-test.sh ``` If your temporary directory is not writable, the unit tests may fail with messages like `fork/exec /tmp/go-build2296620589/b247/config.test: permission denied`. To fix this, set the `TMPDIR` environment variable to something writable, for example `export TMPDIR=~/tmp`. @@ -517,13 +517,13 @@ If your temporary directory is not writable, the unit tests may fail with messag To run the E2E tests locally, you'll need to install Gingko following the instructions [here](https://onsi.github.io/ginkgo/#installing-ginkgo). Run the tests using the dedicated script: ```bash -./scripts/e2e_test.sh +./scripts/relayer_e2e_test.sh ``` To run a specific E2E test, specify the environment variable `GINKGO_FOCUS`, which will then look for [test descriptions](./tests/e2e_test.go#L68) that match the provided input. For example, to run the `Basic Relay` test: ```bash -GINKGO_FOCUS="Basic" ./scripts/e2e_test.sh +GINKGO_FOCUS="Basic" ./scripts/relayer_e2e_test.sh ``` The E2E tests use the `TeleporterMessenger` contract deployment transaction specified in the following files: diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 000000000..6833f172c --- /dev/null +++ b/remappings.txt @@ -0,0 +1,7 @@ +@openzeppelin/contracts@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts +@openzeppelin/contracts-upgradeable@5.0.2=icm-contracts/lib/openzeppelin-contracts-upgradeable/contracts +@forge-std=icm-contracts/lib/forge-std/src +@teleporter=icm-contracts/contracts/teleporter +@subnet-evm=icm-contracts/contracts/subnet-evm +@mocks=icm-contracts/contracts/mocks +@utilities=icm-contracts/contracts/utilities diff --git a/scripts/abi_bindings.sh b/scripts/abi_bindings.sh index 137617cb8..9e7dfb59f 100755 --- a/scripts/abi_bindings.sh +++ b/scripts/abi_bindings.sh @@ -1,22 +1,30 @@ #!/usr/bin/env bash -# Copyright (C) 2024, Ava Labs, Inc. All rights reserved. +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. # See the file LICENSE for licensing terms. set -e -ICM_RELAYER_PATH=$( +REPO_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" cd .. && pwd ) -source $ICM_RELAYER_PATH/scripts/constants.sh -source $ICM_RELAYER_PATH/scripts/versions.sh -source $ICM_CONTRACTS_PATH/scripts/utils.sh +ICM_CONTRACTS_PATH=$REPO_PATH/icm-contracts -setARCH +source $REPO_PATH/scripts/constants.sh +source $REPO_PATH/scripts/versions.sh -# Contract names to generate Go bindings for -DEFAULT_CONTRACT_LIST="BatchCrossChainMessenger" +export ARCH=$(uname -m) +[ $ARCH = x86_64 ] && ARCH=amd64 +echo "ARCH set to $ARCH" + +DEFAULT_CONTRACT_LIST="TeleporterMessenger TeleporterRegistry ExampleERC20 ExampleRewardCalculator TestMessenger ValidatorSetSig NativeTokenStakingManager ERC20TokenStakingManager +TokenHome TokenRemote ERC20TokenHome ERC20TokenHomeUpgradeable ERC20TokenRemote ERC20TokenRemoteUpgradeable NativeTokenHome NativeTokenHomeUpgradeable NativeTokenRemote NativeTokenRemoteUpgradeable +WrappedNativeToken MockERC20SendAndCallReceiver MockNativeSendAndCallReceiver ExampleERC20Decimals IStakingManager ACP99Manager ValidatorManager PoAManager BatchCrossChainMessenger INativeMinter" +PROXY_LIST="TransparentUpgradeableProxy ProxyAdmin" +ACCESS_LIST="OwnableUpgradeable" + +EXTERNAL_LIBS="ValidatorMessages" CONTRACT_LIST= HELP= @@ -40,17 +48,127 @@ if [ "$HELP" = true ]; then fi if ! command -v forge &> /dev/null; then - echo "forge not found." && exit 1 + echo "forge not found. You can install by calling $REPO_PATH/scripts/install_foundry.sh" && exit 1 +fi + +if ! command -v solc &> /dev/null; then + echo "solc not found. See https://docs.soliditylang.org/en/latest/installing-solidity.html for installation instructions" && exit 1 +fi + +# Get the version from solc output +solc_version_output=$(solc --version 2>&1) + +# Extract the semver version from the output +extracted_version=$(solc --version 2>&1 | awk '/Version:/ {print $2}' | awk -F'+' '{print $1}') + +# Check if the extracted version matches the expected version +if ! [[ "$extracted_version" == "$SOLIDITY_VERSION" ]]; then + echo "Expected solc version $SOLIDITY_VERSION, but found $extracted_version. Please install the correct version." && exit 1 fi +# Install abigen +# Temporarily hardcode the version to v0.7.8 since cmd/abigen is removed in the following versions. +# TODO: Remove the hardcoded version and switch to using libevm abigen once the rest of the code is updated to use it. echo "Building subnet-evm abigen" -go install github.com/ava-labs/subnet-evm/cmd/abigen@${SUBNET_EVM_VERSION} +go install github.com/ava-labs/subnet-evm/cmd/abigen@v0.7.8 + +# Solc does not recursively expand remappings, so we must construct them manually +remappings=$(cat $REPO_PATH/remappings.txt) + +# Recursively search for all remappings.txt files in the lib directory. +# For each file, prepend the remapping with the relative path to the file. +while read -r filepath; do + relative_path="${filepath#$REPO_PATH/}" + dir_path=$(dirname "$relative_path") + echo $dir_path + + # Use sed to transform each line with the relative path if it matches the @token=remapping pattern, + # so that each remapping is of the form @token=lib/path/to/remapping + transformed_lines=$(sed -n "s|^\(@[^=]*=\)\(.*\)|\1$dir_path/\2|p" "$filepath") + remappings+=" $transformed_lines " +done < <(find "$REPO_PATH/icm-contracts/lib" -type f -name "remappings.txt" ) + +function convertToLower() { + if [ "$ARCH" = 'arm64' ]; then + echo $1 | perl -ne 'print lc' + else + echo $1 | sed -e 's/\(.*\)/\L\1/' + fi +} + +# Removes a matching string from a comma-separated list +remove_matching_string() { + input_list="$1" + match="$2" + # Split the input list by commas + IFS=',' read -ra elements <<< "$input_list" + + # Initialize an empty result array + result=() -# Force recompile of all contracts to prevent against using previous -# compilations that did not generate new ABI files. -echo "Building Contracts" -cd $ICM_RELAYER_PATH/tests/contracts -forge build --force --extra-output-files abi bin + # Iterate over each element + for element in "${elements[@]}"; do + # Check if the part after the colon matches the given string + if [[ "${element#*:}" != "$match" ]]; then + # If it doesn't match, add the element to the result array + result+=("$element") + fi + done + + # Join the result array with commas and print + (IFS=','; echo "${result[*]}") +} + +function generate_bindings() { + local contract_names=("$@") + for contract_name in "${contract_names[@]}" + do + path=$(find . -name $contract_name.sol) + dir=$(dirname $path) + dir="${dir#./}" + + echo "Building $contract_name..." + mkdir -p $REPO_PATH/out/$contract_name.sol + + combined_json=$REPO_PATH/out/$contract_name.sol/combined-output.json + + cwd=$(pwd) + cd $REPO_PATH + solc --optimize --evm-version $EVM_VERSION --combined-json abi,bin,metadata,ast,devdoc,userdoc --pretty-json $cwd/$dir/$contract_name.sol $remappings > $combined_json + cd $cwd + + # construct the exclude list + contracts=$(jq -r '.contracts | keys | join(",")' $combined_json) + + # Filter out the contract we are generating bindings for + filtered_contracts=$(remove_matching_string $contracts $contract_name) + + gen_path=$REPO_PATH/abi-bindings/go/$dir/$contract_name + mkdir -p $gen_path + echo "Generating Go bindings for $contract_name..." + + if [ -z "$filtered_contracts" ]; then + echo "No external libraries found" + $GOPATH/bin/abigen --pkg $(convertToLower $contract_name) \ + --combined-json $combined_json \ + --type $contract_name \ + --out $gen_path/$contract_name.go + else + # Filter out external libraries + for lib in $EXTERNAL_LIBS; do + filtered_contracts=$(remove_matching_string $filtered_contracts $lib) + done + + $GOPATH/bin/abigen --pkg $(convertToLower $contract_name) \ + --combined-json $combined_json \ + --type $contract_name \ + --out $gen_path/$contract_name.go \ + --exc $filtered_contracts + fi + + echo "Done generating Go bindings for $contract_name." + done +} contract_names=($CONTRACT_LIST) @@ -59,26 +177,15 @@ if [[ -z "${CONTRACT_LIST}" ]]; then contract_names=($DEFAULT_CONTRACT_LIST) fi -cd $ICM_RELAYER_PATH/tests/contracts/src -for contract_name in "${contract_names[@]}" -do - path=$(find . -name $contract_name.sol) - dir=$(dirname $path) - abi_file=$ICM_RELAYER_PATH/tests/contracts/out/$contract_name.sol/$contract_name.abi.json - if ! [ -f $abi_file ]; then - echo "Error: Contract $contract_name abi file not found" - exit 1 - fi +cd $ICM_CONTRACTS_PATH/contracts +generate_bindings "${contract_names[@]}" - echo "Generating Go bindings for $contract_name..." - gen_path=$ICM_RELAYER_PATH/tests/abi-bindings/go/$dir/$contract_name - mkdir -p $gen_path - $GOPATH/bin/abigen --abi $abi_file \ - --pkg $(convertToLower $contract_name) \ - --bin $ICM_RELAYER_PATH/tests/contracts/out/$contract_name.sol/$contract_name.bin \ - --type $contract_name \ - --out $gen_path/$contract_name.go - echo "Done generating Go bindings for $contract_name." -done +contract_names=($PROXY_LIST) +cd $ICM_CONTRACTS_PATH/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/transparent +generate_bindings "${contract_names[@]}" + +contract_names=($ACCESS_LIST) +cd $ICM_CONTRACTS_PATH/lib/openzeppelin-contracts-upgradeable/contracts/access +generate_bindings "${contract_names[@]}" exit 0 diff --git a/scripts/constants.sh b/scripts/constants.sh index 418ef9a60..75eb99d1e 100755 --- a/scripts/constants.sh +++ b/scripts/constants.sh @@ -27,9 +27,6 @@ signature_aggregator_path="$BASE_PATH/build/signature-aggregator" # Set the PATHS GOPATH="$(go env GOPATH)" -ICM_CONTRACTS_PATH="$BASE_PATH"/tests/contracts/lib/icm-contracts -source $ICM_CONTRACTS_PATH/scripts/constants.sh - # Avalabs docker hub repo is avaplatform/icm-relayer. # Here we default to the local image (icm-relayer) as to avoid unintentional pushes # You should probably set it - export DOCKER_REPO='avaplatform/icm-relayer' @@ -45,6 +42,7 @@ git_commit=${RELAYER_COMMIT:-$( git rev-list -1 HEAD )} # We use "export" here instead of just setting a bash variable because we need # to pass this flag to all child processes spawned by the shell. export CGO_CFLAGS="-O -D__BLST_PORTABLE__" + # While CGO_ENABLED doesn't need to be explicitly set, it produces a much more # clear error due to the default value change in go1.20. export CGO_ENABLED=1 diff --git a/scripts/contracts_e2e_test.sh b/scripts/contracts_e2e_test.sh new file mode 100755 index 000000000..e2152b517 --- /dev/null +++ b/scripts/contracts_e2e_test.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +set -e + +REPO_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd +) + +ICM_CONTRACTS_PATH=$REPO_PATH/icm-contracts + +function printHelp() { + echo "Usage: ./scripts/contracts_e2e_test.sh [--component component]" + echo "" + printUsage +} + +function printUsage() { + cat << EOF +Arguments: + --components component1,component2 Comma separated list of test suites to run. Valid components are: + $(echo $valid_components | tr ' ' '\n' | sort | tr '\n' ' ') + (default: all) + --network-dir path Path to the network directory. + If the directory does not exist or is empty, it will be used as the root network directory for a new network. + If the directory exists and is non-empty, the network will be reused. + If not set, a new network will be created at the default root network directory. +Options: + --help Print this help message +EOF +} + +valid_components=$(ls -d $ICM_CONTRACTS_PATH/tests/suites/*/ | xargs -n 1 basename) +components= +reuse_network_dir= +root_dir= +network_dir= +activate_granite=false +reuse_network=false + +while [ $# -gt 0 ]; do + case "$1" in + --components) + if [[ $2 != --* ]]; then + components=$2 + else + echo "Invalid components $2" && printHelp && exit 1 + fi + shift;; + --network-dir) + if [[ $2 != --* ]]; then + reuse_network_dir=$2 + else + echo "Invalid network directory $2" && printHelp && exit 1 + fi + shift;; + --help) + printHelp && exit 0 ;; + --activate-granite) + activate_granite=true;; + *) + echo "Invalid option: $1" && printHelp && exit 1;; + esac + shift +done + +# Run all suites if no component is provided +if [ -z "$components" ]; then + components=$valid_components +fi + +# Exit if invalid component is provided +for component in $(echo $components | tr ',' ' '); do + if [[ $valid_components != *$component* ]]; then + echo "Invalid component $component" && exit 1 + fi +done + +if [ -n "$reuse_network_dir" ]; then + if [ -d "$reuse_network_dir" ] && [ "$(ls -A "$reuse_network_dir")" ]; then + network_dir=$reuse_network_dir + reuse_network=true + echo "Reuse network directory: $network_dir" + else + echo "Network directory $reuse_network_dir does not exist or is empty. Creating a new network at root $reuse_network_dir." + mkdir -p "$reuse_network_dir" + root_dir=$reuse_network_dir + fi +fi + +source "$REPO_PATH"/scripts/constants.sh +source "$REPO_PATH"/scripts/versions.sh + +BASEDIR=${BASEDIR:-"$HOME/.teleporter-deps"} + +cwd=$(pwd) +# Install the avalanchego and subnet-evm binaries +rm -rf $BASEDIR/avalanchego +BASEDIR=$BASEDIR AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego "${REPO_PATH}/scripts/install_avalanchego_release.sh" +BASEDIR=$BASEDIR "${REPO_PATH}/scripts/install_subnetevm_release.sh" + +cp ${BASEDIR}/subnet-evm/subnet-evm ${BASEDIR}/avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +echo "Copied ${BASEDIR}/subnet-evm/subnet-evm binary to ${BASEDIR}/avalanchego/plugins/" + +export AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego +export AVALANCHEGO_PATH=$AVALANCHEGO_BUILD_PATH/avalanchego +export AVAGO_PLUGIN_DIR=$AVALANCHEGO_BUILD_PATH/plugins + +ICM_SERVICES_BUILD_PATH=$BASEDIR/icm-services + +cd $REPO_PATH +# Install signature-aggregator binary +BASEDIR=$BASEDIR ICM_SERVICES_BUILD_PATH=$ICM_SERVICES_BUILD_PATH "${REPO_PATH}/scripts/install_sig_agg_release.sh" +echo "Installed signature-aggregator from icm-services release ${ICM_SERVICES_VERSION}" + +cd $REPO_PATH +if command -v forge &> /dev/null; then + forge build --skip test +else + echo "Forge command not found, attempting to use from $HOME" + $HOME/.foundry/bin/forge build +fi + +cd "$REPO_PATH" + +for component in $(echo $components | tr ',' ' '); do + echo "Building e2e tests for $component" + go run github.com/onsi/ginkgo/v2/ginkgo build ./icm-contracts/tests/suites/$component + + echo "Running e2e tests for $component" + + RUN_E2E=true SIG_AGG_PATH=$ICM_SERVICES_BUILD_PATH/signature-aggregator ./icm-contracts/tests/suites/$component/$component.test \ + --root-network-dir=${root_dir} \ + --reuse-network=${reuse_network} \ + --activate-granite=${activate_granite} \ + --network-dir=${network_dir} \ + --ginkgo.vv \ + --ginkgo.label-filter=${GINKGO_LABEL_FILTER:-""} \ + --ginkgo.focus=${GINKGO_FOCUS:-""} \ + --ginkgo.trace + + echo "$component e2e tests passed" + echo "" +done +exit 0 diff --git a/scripts/deploy_registry.sh b/scripts/deploy_registry.sh new file mode 100755 index 000000000..ca8cf26f6 --- /dev/null +++ b/scripts/deploy_registry.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +set -e + +REPO_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd +) + +# Check that foundry (specifically cast) is installed. +if ! command -v cast &> /dev/null; then + echo "cast not found. You can install by calling $REPO_PATH/scripts/install_foundry.sh" && exit 1 +fi + +# Check that jq is installed. +if ! command -v jq &> /dev/null; then + echo "jq not found. It is required to be installed before proceeding." && exit 1 +fi + +function printHelp() { + echo "Usage: ./scripts/deploy_registry.sh --version --rpc-url --private-key [OPTIONS]" + echo "" + echo "Deploys a selected TeleporterRegistry contract to the specified chain" + echo "For a list of releases, go to https://github.com/ava-labs/icm-contracts/releases" + printUsage +} + +function printUsage() { + cat << EOF +Arguments: + --version Specify the release version to deploy. + --rpc-url Specify the rpc url of the node to use + --private-key Private key of account to deploy TeleporterRegistry +Options: + --help Print this help message +EOF +} + +teleporter_version= +user_private_key= +rpc_url= + +while [ $# -gt 0 ]; do + case "$1" in + --version) + if [[ $2 != --* ]]; then + teleporter_version=$2 + else + echo "Invalid Teleporter version $2" && printHelp && exit 1 + fi + shift;; + --rpc-url) + if [[ $2 != --* ]]; then + rpc_url=$2 + else + echo "Invalid rpc url $2" && printHelp && exit 1 + fi + shift;; + --private-key) + if [[ $2 != --* ]]; then + user_private_key=$2 + else + echo "Invalid private key $2" && printHelp && exit 1 + fi + shift;; + --help) + printHelp && exit 0 ;; + *) + echo "Invalid option: $1" && printHelp && exit 1;; + esac + shift +done + +if [[ $teleporter_version == "" || $rpc_url == "" || $user_private_key == "" ]]; then + echo "Invalid usage. Missing required command line arguments." + printHelp && exit 1 +fi + +teleporter_registry_bytecode=$(curl -sL https://github.com/ava-labs/icm-contracts/releases/download/$teleporter_version/TeleporterRegistry_Bytecode_$teleporter_version.txt) +teleporter_contract_address=$(curl -sL https://github.com/ava-labs/icm-contracts/releases/download/$teleporter_version/TeleporterMessenger_Contract_Address_$teleporter_version.txt) +if [ "$teleporter_registry_bytecode" == "Not Found" ]; then + echo "Error: TeleporterRegistry $teleporter_version byte code not found." + exit 1 +fi + +# Encode the constructor arguments +# TODO: Update to iterate through all release major versions once we have multiple Teleporter versions. +constructor_encoding=$(cast abi-encode "constructor((uint256,address)[])" "[(1, $teleporter_contract_address)]") + +# remove the 0x prefix +constructor_encoding=${constructor_encoding:2} + +# Deploy the TeleporterRegistry contract +deployment_result=$(cast send --private-key $user_private_key --rpc-url $rpc_url --json --create $teleporter_registry_bytecode$constructor_encoding) +teleporter_registry_address=$(echo $deployment_result | jq -r .contractAddress) +deployment_status=$(echo $deployment_result | jq -r .status) +deployment_tx_id=$(echo $deployment_result | jq -r .transactionHash) +if [[ $deployment_status != "0x1" ]]; then + echo "TeleporterRegistry deployment transaction failed. Transaction ID: $deployment_tx_id" + exit 1 +fi +echo "Success! TeleporterRegistry deployed to $teleporter_registry_address in transaction $deployment_tx_id." + +exit 0 diff --git a/scripts/deploy_teleporter.sh b/scripts/deploy_teleporter.sh new file mode 100755 index 000000000..5b851d8ef --- /dev/null +++ b/scripts/deploy_teleporter.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +set -e + +ICM_CONTRACTS_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd ../icm-contracts && pwd +) + +# Check that foundry (specifically cast) is installed. +if ! command -v cast &> /dev/null; then + echo "cast not found. You can install by calling $ICM_CONTRACTS_PATH/scripts/install_foundry.sh" && exit 1 +fi + +# Check that jq is installed. +if ! command -v jq &> /dev/null; then + echo "jq not found. It is required to be installed before proceeding." && exit 1 +fi + +function printHelp() { + echo "Usage: ./scripts/deploy_teleporter.sh --version --rpc-url [OPTIONS]" + echo "" + echo "Deploys a selected TeleporterMessenger contract to the specified chain" + echo "For a list of releases, go to https://github.com/ava-labs/icm-contracts/releases" + printUsage +} + +function printUsage() { + cat << EOF +Arguments: + --version Specify the release version to deploy + --rpc-url Specify the rpc url of the node to use +Options: + --private-key Private key of account to use to fund the Teleporter deployer address, if necessary. + --help Print this help message +EOF +} + +teleporter_version= +user_private_key= +rpc_url= + +while [ $# -gt 0 ]; do + case "$1" in + --version) + if [[ $2 != --* ]]; then + teleporter_version=$2 + else + echo "Invalid Teleporter version $2" && printHelp && exit 1 + fi + shift;; + --rpc-url) + if [[ $2 != --* ]]; then + rpc_url=$2 + else + echo "Invalid rpc url $2" && printHelp && exit 1 + fi + shift;; + --private-key) + if [[ $2 != --* ]]; then + user_private_key=$2 + else + echo "Invalid private key $2" && printHelp && exit 1 + fi + shift;; + --help) + printHelp && exit 0 ;; + *) + echo "Invalid option: $1" && printHelp && exit 1;; + esac + shift +done + +if [[ $teleporter_version == "" || $rpc_url == "" ]]; then + echo "Invalid usage. Teleporter version and RPC URL required." + printHelp && exit 1 +fi + +# Tokens required to deploy the contract. +# Equal to contractCreationGasLimit * contractCreationGasPrice +# from utils/deployment-utils/deployment_utils.go +gas_tokens_required=10000000000000000000 # 10^19 wei = 10 eth + +# Download the artifacts for this release. +teleporter_contract_address=$(curl -sL https://github.com/ava-labs/icm-contracts/releases/download/$teleporter_version/TeleporterMessenger_Contract_Address_$teleporter_version.txt) +echo "TeleporterMessenger $teleporter_version contract address: $teleporter_contract_address" +teleporter_deployer_address=$(curl -sL https://github.com/ava-labs/icm-contracts/releases/download/$teleporter_version/TeleporterMessenger_Deployer_Address_$teleporter_version.txt) +echo "TeleporterMessenger $teleporter_version deployer address: $teleporter_deployer_address" +teleporter_deploy_tx=$(curl -sL https://github.com/ava-labs/icm-contracts/releases/download/$teleporter_version/TeleporterMessenger_Deployment_Transaction_$teleporter_version.txt) +teleporter_messenger_bytecode=$(curl -sL https://github.com/ava-labs/icm-contracts/releases/download/$teleporter_version/TeleporterMessenger_Bytecode_$teleporter_version.txt) +if [ "$teleporter_contract_address" == "Not Found" ]; then + echo "Error: TeleporterMessenger $teleporter_version contract address not found." + exit 1 +fi + +# Check if this TeleporterMessenger version has already been deployed on this chain. +teleporter_contract_code=$(cast codesize $teleporter_contract_address --rpc-url $rpc_url) +if [[ $teleporter_contract_code != "0" ]]; then + echo "TeleporterMessenger $teleporter_version has already been deployed on this chain." && exit 0 +fi + +# Estimate the amount of gas required to deploy the TeleporterMessenger bytecode from the Teleporter +# deployer address in order to simulate the transaction. This will error if the TeleporterMessenger +# contract is unable to be deployed from the deployer address. +cast estimate --rpc-url $rpc_url \ + --from $teleporter_deployer_address \ + --create $teleporter_messenger_bytecode > /dev/null + +# Check the current balance of the deployer address. +deployer_balance=$(cast balance --rpc-url $rpc_url $teleporter_deployer_address) + +if [[ $(echo "$deployer_balance>=$gas_tokens_required" | bc) == 1 ]]; then + echo "Deployer address already funded" +else + # Calculate how many wei the deployer address needs to create the contract. + transfer_amount=$(echo "$gas_tokens_required-$deployer_balance" | bc) + if [[ $user_private_key == "" ]]; then + echo "No private key provided. Deployer address must be funded with $transfer_amount wei to deploy contract" && exit 1 + fi + echo "Funding deployer address with $transfer_amount wei" + cast send --rpc-url $rpc_url --private-key $user_private_key --value $transfer_amount $teleporter_deployer_address +fi + +# Deploy the TeleporterMessenger contract by publishing the raw Nick's method transaction. +echo "Deploying TeleporterMessenger $teleporter_version" +deployment_result=$(cast publish --rpc-url $rpc_url $teleporter_deploy_tx) +deployment_status=$(echo $deployment_result | jq -r .status) +deployment_tx_id=$(echo $deployment_result | jq -r .transactionHash) +if [[ $deployment_status != "0x1" ]]; then + echo "TeleporterMessenger deployment transaction failed. Transaction ID: $deployment_tx_id" + echo "Check failure reason and, if necessary, investigate deployment through state upgrade." + echo "See https://github.com/ava-labs/subnet-evm/tree/master/stateupgrade" + exit 1 +fi + +echo "Success! TeleporterMessenger $teleporter_version deployed to $teleporter_contract_address in transaction $deployment_tx_id." + +exit 0 diff --git a/scripts/install_foundry.sh b/scripts/install_foundry.sh new file mode 100755 index 000000000..0360b1101 --- /dev/null +++ b/scripts/install_foundry.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +set -e + +# The foundry install script uses XDG_CONFIG_HOME as the root of the install. +# This can vary for different environments, so it is set to $HOME for consistency. +export XDG_CONFIG_HOME=$HOME + +FOUNDRY_VERSION=v1.0.0 +curl -L https://raw.githubusercontent.com/foundry-rs/foundry/${FOUNDRY_VERSION}/foundryup/install > /tmp/foundry-install-script +# Set the foundry version in the install script +# Avoid using sed -i due to macos m1 incompatibility +sed "s/\/foundry-rs\/foundry\/master\/foundryup/\/foundry-rs\/foundry\/${FOUNDRY_VERSION}\/foundryup/g" /tmp/foundry-install-script +bash < /tmp/foundry-install-script + +export PATH=$PATH:$HOME/.foundry/bin:$HOME/.foundry:$HOME/.cargo/bin + +foundryup --install ${FOUNDRY_VERSION} diff --git a/scripts/install_sig_agg_release.sh b/scripts/install_sig_agg_release.sh new file mode 100755 index 000000000..32f1fc208 --- /dev/null +++ b/scripts/install_sig_agg_release.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +# See the file LICENSE for licensing terms. + +set -e + +# Load the versions +REPO_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd +) +source "$REPO_PATH"/scripts/versions.sh +source "$REPO_PATH"/scripts/constants.sh + +############################ +# download icm-services +# https://github.com/ava-labs/icm-services/releases +GOARCH=$(go env GOARCH) +GOOS=$(go env GOOS) +BASEDIR=${BASEDIR:-"/tmp/icm-services-release"} +ICM_SERVICES_BUILD_PATH=${ICM_SERVICES_BUILD_PATH-${BASEDIR}/icm-services} + +mkdir -p ${BASEDIR} + +ICM_SERVICES_DOWNLOAD_URL=https://github.com/ava-labs/icm-services/releases/download/${ICM_SERVICES_VERSION}/icm-services_${ICM_SERVICES_VERSION#v}_linux_${GOARCH}.tar.gz +ICM_SERVICES_DOWNLOAD_PATH=${BASEDIR}/icm-services-linux-${GOARCH}-${ICM_SERVICES_VERSION}.tar.gz + +if [[ ${GOOS} == "darwin" ]]; then + ICM_SERVICES_DOWNLOAD_URL=https://github.com/ava-labs/icm-services/releases/download/${ICM_SERVICES_VERSION}/icm-services_${ICM_SERVICES_VERSION#v}_darwin_${GOARCH}.tar.gz + ICM_SERVICES_DOWNLOAD_PATH=${BASEDIR}/icm-services-darwin-${GOARCH}-${ICM_SERVICES_VERSION}.tar.gz +fi + +BUILD_DIR=${ICM_SERVICES_BUILD_PATH}-${ICM_SERVICES_VERSION} + +extract_archive() { + mkdir -p ${BUILD_DIR} + + if [[ ${ICM_SERVICES_DOWNLOAD_PATH} == *.tar.gz ]]; then + tar xzvf ${ICM_SERVICES_DOWNLOAD_PATH} --directory ${BUILD_DIR} + elif [[ ${ICM_SERVICES_DOWNLOAD_PATH} == *.zip ]]; then + unzip ${ICM_SERVICES_DOWNLOAD_PATH} -d ${BUILD_DIR} + mv ${BUILD_DIR}/build/* ${BUILD_DIR} + rm -rf ${BUILD_DIR}/build/ + fi +} + +# first check if we already have the archive +if [[ -f ${ICM_SERVICES_DOWNLOAD_PATH} ]]; then + # if the download path already exists, extract and exit + echo "found icm-services ${ICM_SERVICES_VERSION} at ${ICM_SERVICES_DOWNLOAD_PATH}" + + extract_archive +else + # try to download the archive if it exists + if curl -s --head --request GET ${ICM_SERVICES_DOWNLOAD_URL} | grep "302" > /dev/null; then + echo "${ICM_SERVICES_DOWNLOAD_URL} found" + echo "downloading to ${ICM_SERVICES_DOWNLOAD_PATH}" + curl -L ${ICM_SERVICES_DOWNLOAD_URL} -o ${ICM_SERVICES_DOWNLOAD_PATH} + + extract_archive + else + # else the version is a git commit (or it's invalid) + GIT_CLONE_URL=https://github.com/ava-labs/icm-services.git + GIT_CLONE_PATH=${BASEDIR}/icm-services-repo/ + + # check to see if the repo already exists, if not clone it + if [[ ! -d ${GIT_CLONE_PATH} ]]; then + echo "cloning ${GIT_CLONE_URL} to ${GIT_CLONE_PATH}" + git clone --no-checkout ${GIT_CLONE_URL} ${GIT_CLONE_PATH} + fi + + # check to see if the commitish exists in the repo + WORKDIR=$(pwd) + + cd ${GIT_CLONE_PATH} + + git fetch + + echo "checking out ${ICM_SERVICES_VERSION}" + + # Try to checkout the branch. If it fails, try the commit. + if ! git checkout "origin/${ICM_SERVICES_VERSION}" > /dev/null 2>&1; then + if ! git checkout "${ICM_SERVICES_VERSION}" > /dev/null 2>&1; then + # If the version is in the format of tag-commit, try to extract the commit and checkout. + ICM_SERVICES_VERSION=$(extract_commit "${ICM_SERVICES_VERSION}") + if ! git checkout "${ICM_SERVICES_VERSION}" > /dev/null 2>&1; then + echo + echo "'${ICM_SERVICES_VERSION}' is not a valid release tag, commit hash, or branch name" + exit 1 + fi + fi + fi + + # initialize the submodules + git submodule update --init --recursive + + COMMIT=$(git rev-parse HEAD) + + # use the commit hash instead of the branch name or tag + BUILD_DIR=${ICM_SERVICES_BUILD_PATH}-${COMMIT} + + # if the build-directory doesn't exist, build icm-services + if [[ ! -d ${BUILD_DIR} ]]; then + echo "building icm-services ${COMMIT} to ${BUILD_DIR}" + ./scripts/build_signature_aggregator.sh + mkdir -p ${BUILD_DIR} + cp ./build/signature-aggregator ${BUILD_DIR}/signature-aggregator + fi + + cd $WORKDIR + fi +fi + +SIGNATURE_AGGREGATOR_PATH=${ICM_SERVICES_BUILD_PATH}/signature-aggregator +mkdir -p ${ICM_SERVICES_BUILD_PATH} + +cp ${BUILD_DIR}/signature-aggregator ${SIGNATURE_AGGREGATOR_PATH} + + +echo "Installed signature-aggregator from icm-services release ${ICM_SERVICES_VERSION}" +echo "signature-aggregator Path: ${SIGNATURE_AGGREGATOR_PATH}" + diff --git a/scripts/lint.sh b/scripts/lint.sh index 943aa1258..24fe473bb 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -2,17 +2,89 @@ # Copyright (C) 2023, Ava Labs, Inc. All rights reserved. # See the file LICENSE for licensing terms. -set -o errexit -set -o nounset -set -o pipefail +set -e -RELAYER_PATH=$( - cd "$(dirname "${BASH_SOURCE[0]}")" - cd .. && pwd +REPO_PATH=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + cd .. && pwd ) -source $RELAYER_PATH/scripts/versions.sh +source $REPO_PATH/scripts/versions.sh -go run github.com/golangci/golangci-lint/cmd/golangci-lint run --config=$RELAYER_PATH/.golangci.yml --build-tags=test ./... --timeout 5m +function solFormat() { + # format solidity contracts + echo "Formatting Solidity contracts..." + forge fmt --root $REPO_PATH $REPO_PATH/icm-contracts/contracts/** +} -(cd proto && go run github.com/bufbuild/buf/cmd/buf lint) +function solFormatCheck() { + # format solidity contracts + echo "Checking formatting of Solidity contracts..." + forge fmt --check --root $REPO_PATH $REPO_PATH/icm-contracts/contracts/** +} + +function solLinter() { + # lint solidity contracts + echo "Linting Solidity contracts..." + cd $REPO_PATH + # "solhint **/*.sol" runs differently than "solhint '**/*.sol'", where the latter checks sol files + # in subdirectories. The former only checks sol files in the current directory and directories one level down. + solhint '**/*.sol' --config ./.solhint.json --ignore-path ./.solhintignore --max-warnings 0 +} + +function golangLinter() { + # lint e2e tests go code + echo "Linting Golang code..." + cd $REPO_PATH + go run github.com/golangci/golangci-lint/cmd/golangci-lint run --config=$REPO_PATH/.golangci.yml --build-tags=test ./... --timeout 5m + (cd proto && go run github.com/bufbuild/buf/cmd/buf lint) +} + +function runAll() { + solFormat + solLinter + golangLinter +} + +function printHelp() { + echo "Usage: ./scripts/lint.sh [OPTIONS]" + echo "Lint/Format Teleporter Solidity contracts and E2E tests Golang code." + echo "Pass no parameters to perform all checks" + printUsage +} + +function printUsage() { + echo "Options:" + echo " -sfc, --sol-format-check Check for proper formatted Solidity files. Exits with code 1 if not." + echo " -sf, --sol-format Format Solidity contracts" + echo " -sl, --sol-lint Run the Solidity linter" + echo " -gl, --go-lint Run the Golang linter" + echo " -h, --help Print this help message" +} + +# if we have no args, perform all checks +if [ $# -eq 0 ]; then + runAll + exit 0 +fi + +while [ $# -gt 0 ]; do + case "$1" in + -sfc | --sol-format-check) + solFormatCheck ;; + -sf | --sol-format) + solFormat ;; + -sl | --sol-lint) + solLinter ;; + -gl | --go-lint) + golangLinter ;; + -h | --help) + printHelp ;; + *) + echo "Invalid option: $1" && printHelp && exit 1;; + esac + shift +done + + +exit 0 diff --git a/scripts/protobuf_codegen.sh b/scripts/protobuf_codegen.sh index ae8b88bcf..87c948ef1 100755 --- a/scripts/protobuf_codegen.sh +++ b/scripts/protobuf_codegen.sh @@ -7,12 +7,12 @@ if ! [[ "$0" =~ scripts/protobuf_codegen.sh ]]; then exit 255 fi -RELAYER_PATH=$( +REPO_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" cd .. && pwd ) -source $RELAYER_PATH/scripts/versions.sh +source $REPO_PATH/scripts/versions.sh ## install "protoc-gen-go" PROTOC_GEN_GO_VERSION=$(getDepVersion google.golang.org/protobuf) diff --git a/scripts/e2e_test.sh b/scripts/relayer_e2e_test.sh similarity index 97% rename from scripts/e2e_test.sh rename to scripts/relayer_e2e_test.sh index 116ffaaa3..dd5464166 100755 --- a/scripts/e2e_test.sh +++ b/scripts/relayer_e2e_test.sh @@ -19,7 +19,7 @@ while [ $# -gt 0 ]; do done if [ "$HELP" = true ]; then - echo "Usage: ./scripts/e2e_test.sh [OPTIONS]" + echo "Usage: ./scripts/relayer_e2e_test.sh [OPTIONS]" echo "Run E2E tests for ICM Services." echo "" echo "Options:" diff --git a/scripts/test.sh b/scripts/unit-test.sh similarity index 94% rename from scripts/test.sh rename to scripts/unit-test.sh index 097b71aed..51bae2319 100755 --- a/scripts/test.sh +++ b/scripts/unit-test.sh @@ -17,7 +17,7 @@ while [ $# -gt 0 ]; do done if [ "$HELP" = true ]; then - echo "Usage: ./scripts/test.sh [OPTIONS]" + echo "Usage: ./scripts/unit-test.sh [OPTIONS]" echo "Run unit tests for ICM Services." echo "" echo "Options:" diff --git a/scripts/versions.sh b/scripts/versions.sh index a4ad4eb93..6b2adec46 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -2,6 +2,9 @@ # Copyright (C) 2023, Ava Labs, Inc. All rights reserved. # See the file LICENSE for licensing terms. +set -e +set -o pipefail + BASE_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" cd .. && pwd @@ -28,6 +31,16 @@ function extract_commit() { # This needs to be exported to be picked up by the dockerfile. export GO_VERSION=${GO_VERSION:-$(getDepVersion go)} + +# ICM_SERVICES_VERSION is currently needed for the contracts E2E tests but is not a direct dependency +# since that would create a circular dependency. We should refactor the code until this is no longer the case. +# ICM_SERVICES_VERSION=${ICM_SERVICES_VERSION:-'signature-aggregator-v1.0.0-rc.0'} +ICM_SERVICES_VERSION=${ICM_SERVICES_VERSION:-'9564f00d296c7daeffbf26c4cc4866b3b6e98185'} + # Don't export them as they're used in the context of other calls AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$(extract_commit "$(getDepVersion github.com/ava-labs/avalanchego)")} SUBNET_EVM_VERSION=${SUBNET_EVM_VERSION:-$(extract_commit "$(getDepVersion github.com/ava-labs/subnet-evm)")} + +# Extract the Solidity version from foundry.toml +SOLIDITY_VERSION=$(awk -F"'" '/^solc_version/ {print $2}' $BASE_PATH/foundry.toml) +EVM_VERSION=$(awk -F"'" '/^evm_version/ {print $2}' $BASE_PATH/foundry.toml) diff --git a/slither.config.json b/slither.config.json new file mode 100644 index 000000000..bd02b0200 --- /dev/null +++ b/slither.config.json @@ -0,0 +1,3 @@ +{ + "filter_paths": "icm-contracts/lib" +} diff --git a/tests/allowed_addresses.go b/tests/allowed_addresses.go index c77205255..d3609c0b3 100644 --- a/tests/allowed_addresses.go +++ b/tests/allowed_addresses.go @@ -8,10 +8,10 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/database" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/relayer/config" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/libevm/common" diff --git a/tests/basic_relay.go b/tests/basic_relay.go index 22700d669..4c06833b3 100644 --- a/tests/basic_relay.go +++ b/tests/basic_relay.go @@ -9,10 +9,10 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/database" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/crypto" diff --git a/tests/batch_relay.go b/tests/batch_relay.go index 65ebbcbed..93b35e2ec 100644 --- a/tests/batch_relay.go +++ b/tests/batch_relay.go @@ -8,9 +8,9 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" diff --git a/tests/contracts/lib/forge-std b/tests/contracts/lib/forge-std deleted file mode 160000 index d44c4fbbb..000000000 --- a/tests/contracts/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d44c4fbbb9ff054fb334babbdd34f9b6e899b3d6 diff --git a/tests/contracts/lib/icm-contracts b/tests/contracts/lib/icm-contracts deleted file mode 160000 index c64f31020..000000000 --- a/tests/contracts/lib/icm-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c64f31020739fd318228ac545e5ff936a4feedf0 diff --git a/tests/contracts/remappings.txt b/tests/contracts/remappings.txt deleted file mode 100644 index 35224d957..000000000 --- a/tests/contracts/remappings.txt +++ /dev/null @@ -1,3 +0,0 @@ -@openzeppelin/contracts@4.8.1/=lib/teleporter/contracts/lib/openzeppelin-contracts/contracts/ -@avalabs/subnet-evm-contracts@1.2.0/=lib/teleporter/contracts/lib/subnet-evm/contracts/ -@teleporter/=lib/teleporter/contracts/src/Teleporter/ diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 33ce1ebb2..813a83ceb 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -18,8 +18,8 @@ import ( "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/icm-contracts/tests/network" - teleporterTestUtils "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + teleporterTestUtils "github.com/ava-labs/icm-services/icm-contracts/tests/utils" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/icm-services/utils" "github.com/ava-labs/libevm/common" @@ -51,6 +51,10 @@ func TestMain(m *testing.M) { } func TestE2E(t *testing.T) { + if os.Getenv("RUN_E2E") == "" { + t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") + } + // Handle SIGINT and SIGTERM signals. signalChan := make(chan os.Signal, 2) signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) @@ -61,10 +65,6 @@ func TestE2E(t *testing.T) { os.Exit(1) }() - if os.Getenv("RUN_E2E") == "" { - t.Skip("Environment variable RUN_E2E not set; skipping E2E tests") - } - RegisterFailHandler(ginkgo.Fail) ginkgo.RunSpecs(t, "Relayer e2e test") } diff --git a/tests/manual_message.go b/tests/manual_message.go index cbe22241e..52d8e8893 100644 --- a/tests/manual_message.go +++ b/tests/manual_message.go @@ -12,10 +12,10 @@ import ( "net/http" "time" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" - teleporterTestUtils "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + teleporterTestUtils "github.com/ava-labs/icm-services/icm-contracts/tests/utils" offchainregistry "github.com/ava-labs/icm-services/messages/off-chain-registry" "github.com/ava-labs/icm-services/relayer/api" testUtils "github.com/ava-labs/icm-services/tests/utils" diff --git a/tests/relay_message_api.go b/tests/relay_message_api.go index ca1c1c567..1d3b44e7c 100644 --- a/tests/relay_message_api.go +++ b/tests/relay_message_api.go @@ -14,10 +14,10 @@ import ( "github.com/ava-labs/avalanchego/ids" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" - teleporterTestUtils "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + teleporterTestUtils "github.com/ava-labs/icm-services/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/relayer/api" testUtils "github.com/ava-labs/icm-services/tests/utils" ethereum "github.com/ava-labs/libevm" diff --git a/tests/shared_db.go b/tests/shared_db.go index e898676b9..a0285a1ba 100644 --- a/tests/shared_db.go +++ b/tests/shared_db.go @@ -4,9 +4,9 @@ import ( "context" "sync" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/libevm/crypto" "github.com/ava-labs/libevm/log" diff --git a/tests/signature_aggregator_api.go b/tests/signature_aggregator_api.go index b9a0f9d0a..457990ba7 100644 --- a/tests/signature_aggregator_api.go +++ b/tests/signature_aggregator_api.go @@ -14,9 +14,9 @@ import ( "time" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/signature-aggregator/api" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/libevm/log" diff --git a/tests/signature_aggregator_epoch_api.go b/tests/signature_aggregator_epoch_api.go index f3b92e60d..6b2a69dd6 100644 --- a/tests/signature_aggregator_epoch_api.go +++ b/tests/signature_aggregator_epoch_api.go @@ -15,9 +15,9 @@ import ( pchainapi "github.com/ava-labs/avalanchego/vms/platformvm/api" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/signature-aggregator/api" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/libevm/log" diff --git a/tests/utils/utils.go b/tests/utils/utils.go index d6778d37c..7f80a13e7 100644 --- a/tests/utils/utils.go +++ b/tests/utils/utils.go @@ -19,15 +19,15 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/logging" - teleportermessenger "github.com/ava-labs/icm-contracts/abi-bindings/go/teleporter/TeleporterMessenger" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/utils" - teleporterTestUtils "github.com/ava-labs/icm-contracts/tests/utils" + teleportermessenger "github.com/ava-labs/icm-services/abi-bindings/go/teleporter/TeleporterMessenger" + batchcrosschainmessenger "github.com/ava-labs/icm-services/abi-bindings/go/utilities/BatchCrossChainMessenger" "github.com/ava-labs/icm-services/config" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" + teleporterTestUtils "github.com/ava-labs/icm-services/icm-contracts/tests/utils" offchainregistry "github.com/ava-labs/icm-services/messages/off-chain-registry" relayercfg "github.com/ava-labs/icm-services/relayer/config" signatureaggregatorcfg "github.com/ava-labs/icm-services/signature-aggregator/config" - batchcrosschainmessenger "github.com/ava-labs/icm-services/tests/abi-bindings/go/BatchCrossChainMessenger" relayerUtils "github.com/ava-labs/icm-services/utils" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/types" @@ -549,6 +549,7 @@ func DeployBatchCrossChainMessenger( l1.RPCClient, teleporter.TeleporterRegistryAddress(l1), teleporterManager, + teleporter.GetLatestTeleporterVersion(l1), ) Expect(err).Should(BeNil()) diff --git a/tests/validators_only_network.go b/tests/validators_only_network.go index 5aa1ef4d8..31c77c8f4 100644 --- a/tests/validators_only_network.go +++ b/tests/validators_only_network.go @@ -23,10 +23,10 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/warp" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/config" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" "github.com/ava-labs/icm-services/peers/validators" "github.com/ava-labs/icm-services/signature-aggregator/api" testUtils "github.com/ava-labs/icm-services/tests/utils" diff --git a/tests/warp_api.go b/tests/warp_api.go index fe41dcc82..aef7f9c46 100644 --- a/tests/warp_api.go +++ b/tests/warp_api.go @@ -13,9 +13,9 @@ import ( "strings" "time" - "github.com/ava-labs/icm-contracts/tests/interfaces" - "github.com/ava-labs/icm-contracts/tests/network" - "github.com/ava-labs/icm-contracts/tests/utils" + "github.com/ava-labs/icm-services/icm-contracts/tests/interfaces" + "github.com/ava-labs/icm-services/icm-contracts/tests/network" + "github.com/ava-labs/icm-services/icm-contracts/tests/utils" testUtils "github.com/ava-labs/icm-services/tests/utils" "github.com/ava-labs/libevm/crypto" "github.com/ava-labs/libevm/log"